@@ -18,7 +18,7 @@ import CopyButton from "./CodeSnippet/CopyButton";
1818import SegmentedControl from "./SegmentedControl" ;
1919
2020// Define SDK type
21- export type SDKType = "realtime" | "rest" | null ;
21+ export type SDKType = "realtime" | "rest" | "fe" | "be" | null ;
2222
2323// Define API key types
2424export type ApiKeysItem = {
@@ -169,6 +169,21 @@ const CodeSnippet: React.FC<CodeSnippetProps> = ({
169169 [ ] ,
170170 ) ;
171171
172+ // Helper to find the code element within pre's children (handles both single element and array)
173+ const findCodeElement = useCallback (
174+ ( preChildren : React . ReactNode ) : React . ReactElement | null => {
175+ if ( isValidElement ( preChildren ) ) {
176+ return preChildren ;
177+ }
178+ if ( Array . isArray ( preChildren ) ) {
179+ const codeEl = preChildren . find ( ( c ) => isValidElement ( c ) ) ;
180+ return codeEl && isValidElement ( codeEl ) ? codeEl : null ;
181+ }
182+ return null ;
183+ } ,
184+ [ ] ,
185+ ) ;
186+
172187 const { codeData, languages, sdkTypes, isSinglePlainCommand } =
173188 useMemo ( ( ) => {
174189 const childrenArray = Children . toArray ( children ) ;
@@ -178,20 +193,17 @@ const CodeSnippet: React.FC<CodeSnippetProps> = ({
178193
179194 const isSinglePlainCommand =
180195 childrenArray . length === 1 &&
181- [ "language-shell" , "language-text" ] . some (
182- ( lang ) =>
183- isValidElement ( childrenArray [ 0 ] ) &&
184- isValidElement ( childrenArray [ 0 ] . props . children ) &&
185- childrenArray [ 0 ] . props . children . props . className ?. includes ( lang ) ,
186- ) ;
196+ [ "language-shell" , "language-text" ] . some ( ( lang ) => {
197+ if ( ! isValidElement ( childrenArray [ 0 ] ) ) return false ;
198+ const codeEl = findCodeElement ( childrenArray [ 0 ] . props . children ) ;
199+ return codeEl ?. props . className ?. includes ( lang ) ;
200+ } ) ;
187201
188202 childrenArray . forEach ( ( child ) => {
189203 if ( ! isValidElement ( child ) ) return ;
190204
191205 const preElement = child ;
192- const codeElement = isValidElement ( preElement . props . children )
193- ? preElement . props . children
194- : null ;
206+ const codeElement = findCodeElement ( preElement . props . children ) ;
195207
196208 if ( ! codeElement ) return ;
197209
@@ -203,6 +215,10 @@ const CodeSnippet: React.FC<CodeSnippetProps> = ({
203215 sdkTypes . add ( "realtime" ) ;
204216 } else if ( codeLanguage . startsWith ( "rest_" ) ) {
205217 sdkTypes . add ( "rest" ) ;
218+ } else if ( codeLanguage . startsWith ( "fe_" ) ) {
219+ sdkTypes . add ( "fe" ) ;
220+ } else if ( codeLanguage . startsWith ( "be_" ) ) {
221+ sdkTypes . add ( "be" ) ;
206222 }
207223
208224 if ( ! languages . includes ( codeLanguage ) ) {
@@ -219,7 +235,7 @@ const CodeSnippet: React.FC<CodeSnippetProps> = ({
219235 sdkTypes,
220236 isSinglePlainCommand,
221237 } ;
222- } , [ children , extractLanguageFromCode ] ) ;
238+ } , [ children , extractLanguageFromCode , findCodeElement ] ) ;
223239
224240 const resolvedSdk : SDKType = useMemo ( ( ) => {
225241 if ( sdkTypes . size === 1 && sdk && ! sdkTypes . has ( sdk ) ) {
@@ -228,7 +244,8 @@ const CodeSnippet: React.FC<CodeSnippetProps> = ({
228244 return sdk ?? null ;
229245 } , [ sdk , sdkTypes ] ) ;
230246
231- const showSDKSelector = sdkTypes . size > 0 ;
247+ // Only show SDK selector for realtime/rest types, not for fe/be (which are controlled by page-level selector)
248+ const showSDKSelector = sdkTypes . has ( "realtime" ) || sdkTypes . has ( "rest" ) ;
232249
233250 const filteredLanguages = useMemo ( ( ) => {
234251 const filtered =
@@ -256,6 +273,19 @@ const CodeSnippet: React.FC<CodeSnippetProps> = ({
256273 } , [ resolvedSdk , showSDKSelector , languages , languageOrdering ] ) ;
257274
258275 const activeLanguage = useMemo ( ( ) => {
276+ // For fe/be SDK types (controlled by page-level selector), construct the full language
277+ if ( resolvedSdk === "fe" || resolvedSdk === "be" ) {
278+ const fullLang = `${ resolvedSdk } _${ lang } ` ;
279+ // Verify this language exists in available languages
280+ if ( languages . includes ( fullLang ) ) {
281+ return fullLang ;
282+ }
283+ // Fall back to first language with this prefix
284+ const prefixMatch = languages . find ( ( l ) => l . startsWith ( `${ resolvedSdk } _` ) ) ;
285+ if ( prefixMatch ) return prefixMatch ;
286+ }
287+
288+ // For realtime/rest SDK types
259289 if ( resolvedSdk && sdkTypes . has ( resolvedSdk ) ) {
260290 return `${ resolvedSdk } _${ lang } ` ;
261291 }
@@ -399,6 +429,8 @@ const CodeSnippet: React.FC<CodeSnippetProps> = ({
399429
400430 const showLanguageSelector = ! fixed && filteredLanguages . length > 0 ;
401431 const showFullSelector = filteredLanguages . length > 1 ;
432+ // Show a read-only language label when fixed (controlled by external selector)
433+ const showFixedLanguageLabel = fixed && activeLanguage ;
402434
403435 const renderContent = useMemo ( ( ) => {
404436 if ( ! activeLanguage ) return null ;
@@ -501,6 +533,26 @@ const CodeSnippet: React.FC<CodeSnippetProps> = ({
501533 </ div >
502534 ) }
503535
536+ { showFixedLanguageLabel && (
537+ < div
538+ className = { cn (
539+ "border-b border-neutral-300 dark:border-neutral-1000 h-[2.125rem] inline-flex items-center px-3 w-full" ,
540+ { "rounded-t-lg" : ! headerRow } ,
541+ ) }
542+ >
543+ < div className = "inline-flex items-center" >
544+ < Icon
545+ name = { getLanguageInfo ( activeLanguage ) . icon }
546+ size = "16px"
547+ additionalCSS = "mr-2"
548+ />
549+ < span className = "ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none" >
550+ { getLanguageInfo ( activeLanguage ) . label }
551+ </ span >
552+ </ div >
553+ </ div >
554+ ) }
555+
504556 { showLanguageSelector &&
505557 ( showFullSelector ? (
506558 < LanguageSelector
0 commit comments