diff --git a/src/app/[locale]/docs/layout.tsx b/src/app/[locale]/docs/layout.tsx index 8a7f236..5577299 100644 --- a/src/app/[locale]/docs/layout.tsx +++ b/src/app/[locale]/docs/layout.tsx @@ -5,25 +5,15 @@ import { websiteConfig } from '@/config/website'; import { docsI18nConfig } from '@/lib/docs/i18n'; import { source } from '@/lib/docs/source'; import { getUrlWithLocale } from '@/lib/urls/urls'; -import { I18nProvider, type Translations } from 'fumadocs-ui/i18n'; import { DocsLayout } from 'fumadocs-ui/layouts/docs'; import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; -import { BookIcon, HomeIcon } from 'lucide-react'; +import { HomeIcon } from 'lucide-react'; import type { Locale } from 'next-intl'; import { getTranslations } from 'next-intl/server'; import type { ReactNode } from 'react'; import '@/styles/mdx.css'; -// available languages that will be displayed on UI -// make sure `locale` is consistent with your i18n config -const locales = Object.entries(websiteConfig.i18n.locales).map( - ([locale, data]) => ({ - name: data.name, - locale, - }) -); - interface DocsLayoutProps { children: ReactNode; params: Promise<{ locale: Locale }>; @@ -50,17 +40,6 @@ export default async function DocsRootLayout({ const { locale } = await params; const t = await getTranslations({ locale, namespace: 'DocsPage' }); - // Create translations object for fumadocs-ui from our message files - const translations: Partial = { - toc: t('toc'), - search: t('search'), - lastUpdate: t('lastUpdate'), - searchNoResult: t('searchNoResult'), - previousPage: t('previousPage'), - nextPage: t('nextPage'), - chooseLanguage: t('chooseLanguage'), - }; - // Docs layout configurations const showLocaleSwitch = Object.keys(websiteConfig.i18n.locales).length > 1; const docsOptions: BaseLayoutProps = { @@ -85,14 +64,14 @@ export default async function DocsRootLayout({ }, ...(websiteConfig.metadata.social?.twitter ? [ - { - type: 'icon' as const, - icon: , - text: 'X', - url: websiteConfig.metadata.social.twitter, - secondary: true, - }, - ] + { + type: 'icon' as const, + icon: , + text: 'X', + url: websiteConfig.metadata.social.twitter, + secondary: true, + }, + ] : []), ], themeSwitch: { @@ -103,10 +82,8 @@ export default async function DocsRootLayout({ }; return ( - - - {children} - - + + {children} + ); } diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 4bb1ee8..0932f26 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -58,7 +58,7 @@ export default async function LocaleLayout({ )} > - + {children} diff --git a/src/app/[locale]/providers.tsx b/src/app/[locale]/providers.tsx index d7b9616..06a8ee6 100644 --- a/src/app/[locale]/providers.tsx +++ b/src/app/[locale]/providers.tsx @@ -4,9 +4,16 @@ import { ActiveThemeProvider } from '@/components/layout/active-theme-provider'; import { PaymentProvider } from '@/components/layout/payment-provider'; import { TooltipProvider } from '@/components/ui/tooltip'; import { websiteConfig } from '@/config/website'; +import { Translations } from 'fumadocs-ui/i18n'; import { RootProvider } from 'fumadocs-ui/provider'; +import { useTranslations } from 'next-intl'; import { ThemeProvider, useTheme } from 'next-themes'; -import type { PropsWithChildren } from 'react'; +import type { ReactNode } from 'react'; + +interface ProvidersProps { + children: ReactNode; + locale: string; +} /** * Providers @@ -19,10 +26,31 @@ import type { PropsWithChildren } from 'react'; * - TooltipProvider: Provides the tooltip to the app. * - PaymentProvider: Provides the payment state to the app. */ -export function Providers({ children }: PropsWithChildren) { +export function Providers({ children, locale }: ProvidersProps) { const theme = useTheme(); const defaultMode = websiteConfig.metadata.mode?.defaultMode ?? 'system'; + // available languages that will be displayed in the docs UI + // make sure `locale` is consistent with your i18n config + const locales = Object.entries(websiteConfig.i18n.locales).map( + ([locale, data]) => ({ + name: data.name, + locale, + }) + ); + + // translations object for fumadocs-ui from our message files + const t = useTranslations('DocsPage'); + const translations: Partial = { + toc: t('toc'), + search: t('search'), + lastUpdate: t('lastUpdate'), + searchNoResult: t('searchNoResult'), + previousPage: t('previousPage'), + nextPage: t('nextPage'), + chooseLanguage: t('chooseLanguage'), + }; + return ( - + {children} diff --git a/src/app/api/search/route.ts b/src/app/api/search/route.ts index e91df60..7092ea6 100644 --- a/src/app/api/search/route.ts +++ b/src/app/api/search/route.ts @@ -55,57 +55,19 @@ const searchAPI = createI18nSearchAPI('advanced', { }); /** + * Fumadocs 15.2.8 fixed the bug that the `locale` is not passed to the search API + * + * ref: + * https://x.com/indie_maker_fox/status/1913457083997192589 + * + * NOTICE: + * Fumadocs 15.1.2 has a bug that the `locale` is not passed to the search API * 1. Wrap the GET handler for debugging docs search * 2. Detect locale from referer header, and add the locale parameter to the search API * 3. Fumadocs core searchAPI get `locale` from searchParams, and pass it to the search API * https://github.com/fuma-nama/fumadocs/blob/dev/packages/core/src/search/orama/create-endpoint.ts#L19 */ export const GET = async (request: Request) => { - const url = new URL(request.url); - const query = url.searchParams.get('query') || ''; - let locale = url.searchParams.get('locale') || docsI18nConfig.defaultLanguage; - - // detect locale from referer header - const referer = request.headers.get('referer'); - if (referer) { - try { - const refererUrl = new URL(referer); - console.log('search, referer pathname:', refererUrl.pathname); - const refererPathParts = refererUrl.pathname.split('/').filter(Boolean); - console.log('search, referer path parts:', refererPathParts); - if ( - refererPathParts.length > 0 && - docsI18nConfig.languages.includes(refererPathParts[0]) - ) { - locale = refererPathParts[0]; - console.log(`search, detected locale from referer: ${locale}`); - } - } catch (e) { - console.error('search, error parsing referer:', e); - } - } - - console.log(`search, request: query="${query}", detected locale="${locale}"`); - - // ensure locale parameter is passed to search API - const searchUrl = new URL(url); - searchUrl.searchParams.set('locale', locale); - - const modifiedRequest = new Request(searchUrl, { - headers: request.headers, - method: request.method, - body: request.body, - cache: request.cache, - credentials: request.credentials, - integrity: request.integrity, - keepalive: request.keepalive, - mode: request.mode, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - signal: request.signal, - }); - - const response = await searchAPI.GET(modifiedRequest); + const response = await searchAPI.GET(request); return response; };