Compare commits
3 Commits
cloudflare
...
dev/fumado
Author | SHA1 | Date | |
---|---|---|---|
|
0297c3cd88 | ||
|
f3fb9824f4 | ||
|
b577847b4b |
10
package.json
10
package.json
@ -20,9 +20,9 @@
|
||||
"@ai-sdk/openai": "^1.1.13",
|
||||
"@aws-sdk/client-s3": "^3.758.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.758.0",
|
||||
"@content-collections/core": "^0.8.0",
|
||||
"@content-collections/mdx": "^0.2.0",
|
||||
"@content-collections/next": "^0.2.4",
|
||||
"@content-collections/core": "^0.8.2",
|
||||
"@content-collections/mdx": "^0.2.2",
|
||||
"@content-collections/next": "^0.2.6",
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@dnd-kit/modifiers": "^9.0.0",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
@ -83,8 +83,8 @@
|
||||
"drizzle-orm": "^0.39.3",
|
||||
"embla-carousel-react": "^8.5.2",
|
||||
"framer-motion": "^12.4.7",
|
||||
"fumadocs-core": "^15.1.2",
|
||||
"fumadocs-ui": "^15.1.2",
|
||||
"fumadocs-core": "^15.2.8",
|
||||
"fumadocs-ui": "^15.2.8",
|
||||
"geist": "^1.3.1",
|
||||
"input-otp": "^1.4.2",
|
||||
"lucide-react": "^0.483.0",
|
||||
|
1277
pnpm-lock.yaml
generated
1277
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -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<Translations> = {
|
||||
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 = {
|
||||
@ -103,10 +82,8 @@ export default async function DocsRootLayout({
|
||||
};
|
||||
|
||||
return (
|
||||
<I18nProvider locales={locales} locale={locale} translations={translations}>
|
||||
<DocsLayout tree={source.pageTree[locale]} {...docsOptions}>
|
||||
{children}
|
||||
</DocsLayout>
|
||||
</I18nProvider>
|
||||
);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ export default async function LocaleLayout({
|
||||
)}
|
||||
>
|
||||
<NextIntlClientProvider>
|
||||
<Providers>
|
||||
<Providers locale={locale}>
|
||||
{children}
|
||||
|
||||
<Toaster richColors position="top-right" offset={64} />
|
||||
|
@ -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<Translations> = {
|
||||
toc: t('toc'),
|
||||
search: t('search'),
|
||||
lastUpdate: t('lastUpdate'),
|
||||
searchNoResult: t('searchNoResult'),
|
||||
previousPage: t('previousPage'),
|
||||
nextPage: t('nextPage'),
|
||||
chooseLanguage: t('chooseLanguage'),
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
@ -31,7 +59,7 @@ export function Providers({ children }: PropsWithChildren) {
|
||||
disableTransitionOnChange
|
||||
>
|
||||
<ActiveThemeProvider>
|
||||
<RootProvider theme={theme}>
|
||||
<RootProvider theme={theme} i18n={{ locale, locales, translations }}>
|
||||
<TooltipProvider>
|
||||
<PaymentProvider>{children}</PaymentProvider>
|
||||
</TooltipProvider>
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -28,7 +28,16 @@ export default function Example() {
|
||||
className="bg-transparent px-4 py-2 text-sm focus-visible:outline-none"
|
||||
/>
|
||||
</div>
|
||||
<DynamicCodeBlock lang={lang} code={code} options={{}} />
|
||||
<DynamicCodeBlock
|
||||
lang={lang}
|
||||
code={code}
|
||||
options={{
|
||||
themes: {
|
||||
light: 'github-light',
|
||||
dark: 'github-dark'
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user