import { JwtSecretUpdateStatus } from '@supabase/shared-types/out/events' import { AlertCircle, Loader } from 'lucide-react' import Link from 'next/link' import { useState } from 'react' import { useParams } from 'common' import { useApiKeysVisibility } from 'components/interfaces/APIKeys/hooks/useApiKeysVisibility' import Panel from 'components/ui/Panel' import { getKeys, useAPIKeysQuery } from 'data/api-keys/api-keys-query' import { useJwtSecretUpdatingStatusQuery } from 'data/config/jwt-secret-updating-status-query' import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query' import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { Input, SimpleCodeBlock } from 'ui' const generateInitSnippet = (endpoint: string) => ({ js: ` import { createClient } from '@supabase/supabase-js' const supabaseUrl = '${endpoint}' const supabaseKey = process.env.SUPABASE_KEY const supabase = createClient(supabaseUrl, supabaseKey)`, dart: ` const supabaseUrl = '${endpoint}'; const supabaseKey = String.fromEnvironment('SUPABASE_KEY'); Future main() async { await Supabase.initialize(url: supabaseUrl, anonKey: supabaseKey); runApp(MyApp()); }`, }) export const APIKeys = () => { const { ref: projectRef } = useParams() const { projectConnectionJavascriptExample: javascriptExampleEnabled, projectConnectionDartExample: dartExampleEnabled, } = useIsFeatureEnabled([ 'project_connection:javascript_example', 'project_connection:dart_example', ]) const availableLanguages = [ { name: javascriptExampleEnabled ? 'Javascript' : 'Typescript', key: 'js', }, ...(dartExampleEnabled ? [{ name: 'Dart', key: 'dart' }] : []), ] const [selectedLanguage, setSelectedLanguage] = useState(availableLanguages[0]) const { data: settings, isError: isProjectSettingsError, isLoading: isProjectSettingsLoading, } = useProjectSettingsV2Query({ projectRef }) const { canReadAPIKeys } = useApiKeysVisibility() const { data: apiKeys } = useAPIKeysQuery({ projectRef }, { enabled: canReadAPIKeys }) const { anonKey, serviceKey } = getKeys(apiKeys) const isApiKeysEmpty = !anonKey && !serviceKey const { data, isError: isJwtSecretUpdateStatusError, isLoading: isJwtSecretUpdateStatusLoading, } = useJwtSecretUpdatingStatusQuery( { projectRef }, { enabled: !isProjectSettingsLoading && isApiKeysEmpty } ) // Only show JWT loading state if the query is actually enabled const showJwtLoading = isJwtSecretUpdateStatusLoading && !isProjectSettingsLoading && isApiKeysEmpty const jwtSecretUpdateStatus = data?.jwtSecretUpdateStatus const isNotUpdatingJwtSecret = jwtSecretUpdateStatus === undefined || jwtSecretUpdateStatus === JwtSecretUpdateStatus.Updated const protocol = settings?.app_config?.protocol ?? 'https' const endpoint = settings?.app_config?.endpoint const apiUrl = `${protocol}://${endpoint ?? '-'}` const clientInitSnippet: any = generateInitSnippet(apiUrl) const selectedLanguageSnippet = !!selectedLanguage ? clientInitSnippet[selectedLanguage.key] : 'No snippet available' return (
Project API

Your API is secured behind an API gateway which requires an API Key for every request.
You can use the parameters below to use Supabase client libraries.

} > {isProjectSettingsError || isJwtSecretUpdateStatusError ? (

{isProjectSettingsError ? 'Failed to retrieve API keys' : 'Failed to update JWT secret'}

) : isProjectSettingsLoading ? (

Retrieving API keys

) : isApiKeysEmpty ? (

Retrieving API keys

) : showJwtLoading ? (

JWT secret is being updated

) : ( <>

API Key

{anonKey?.name} public
} copy={canReadAPIKeys && isNotUpdatingJwtSecret} reveal={anonKey?.name !== 'anon' && canReadAPIKeys && isNotUpdatingJwtSecret} value={ !canReadAPIKeys ? 'You need additional permissions to view API keys' : jwtSecretUpdateStatus === JwtSecretUpdateStatus.Failed ? 'JWT secret update failed, new API key may have issues' : jwtSecretUpdateStatus === JwtSecretUpdateStatus.Updating ? 'Updating JWT secret...' : anonKey?.api_key } onChange={() => {}} descriptionText={

This key is safe to use in a browser if you have enabled Row Level Security (RLS) for your tables and configured policies. You may also use the service key which can be found{' '} here {' '} to bypass RLS.

} />
{availableLanguages.length > 0 && (
{availableLanguages.map((language) => { const isSelected = selectedLanguage.key === language.key return (
setSelectedLanguage(language)} > {language.name}
) })}
{selectedLanguageSnippet}
)} )}
) }