Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync #1192

Merged
merged 8 commits into from
Dec 27, 2024
Merged

Sync #1192

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 81 additions & 56 deletions apps/docs/content/docs/ui/internationalization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,6 @@ export const source = loader({
});
```

Update the usages to your source to include a locale code:

```ts
import { source } from '@/lib/source';

// get page tree
source.pageTree[params.lang];

// get page
source.getPage(params.slug, params.lang);

// get pages
source.getPages(params.lang);
```

Note that without providing a locale code, it uses your default locale instead.
You can see [Source API](/docs/headless/source-api) for other usages.

### Middleware

Create a middleware that redirects users to appropriate locale.
Expand All @@ -83,28 +65,57 @@ Create a middleware that redirects users to appropriate locale.

See [Middleware](/docs/headless/internationalization#middleware) for customisable options.

### Root Layout
### Routing

Create a dynamic route `/app/[lang]`, and move all special files from `/app` to
the folder.

A `I18nProvider` is needed for localization. Wrap the root provider inside your I18n provider.
A `I18nProvider` is needed for localization.
Wrap the root provider inside your I18n provider, and provide available languages & translations to it.

Note that only English translations are provided by default.

```tsx
import { RootProvider } from 'fumadocs-ui/provider';
import { I18nProvider } from 'fumadocs-ui/i18n';
import { I18nProvider, type Translations } from 'fumadocs-ui/i18n';

const cn: Translations = {
search: 'Translated Content',
// other props
};

export default function RootLayout({
// available languages that will be displayed on UI
// make sure `locale` is consistent with your i18n config
const locales = [
{
name: 'English',
locale: 'en',
},
{
name: 'Chinese',
locale: 'cn',
},
];

export default async function RootLayout({
params,
children,
}: {
params: { lang: string };
params: Promise<{ lang: string }>;
children: React.ReactNode;
}) {
return (
<html lang={params.lang}>
<html lang={(await params).lang}>
<body>
<I18nProvider locale={params.lang}>
<I18nProvider
locale={(await params).lang}
locales={locales}
translations={
{
cn,
}[(await params).lang]
}
>
<RootProvider>{children}</RootProvider>
</I18nProvider>
</body>
Expand All @@ -113,47 +124,61 @@ export default function RootLayout({
}
```

### Writing Documents
### Source

see [Page Conventions](/docs/ui/page-conventions#internationalization) to learn how to organize your documents.
Update the usages to your source to include a locale code:

### Search
```ts
import { source } from '@/lib/source';

Configure i18n on your search solution.
// get page tree
source.pageTree[params.lang];

You don't need further changes if you're using the `createFromSource` shortcut.
// get page
source.getPage(params.slug, params.lang);

For the built-in Orama search, see [Search I18n](/docs/headless/search/orama#internationalization).
// get pages
source.getPages(params.lang);
```

### Adding Translations
like:

We only provide English translation by default, you have to pass your translations to the provider.
```tsx title="app/[lang]/layout.tsx"
import { source } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/docs';
import type { ReactNode } from 'react';

```tsx
import { I18nProvider } from 'fumadocs-ui/i18n';

<I18nProvider
locales={[
{
name: 'English',
locale: 'en',
},
{
name: 'Chinese',
locale: 'cn',
},
]}
translations={
{
cn: {
search: 'Translated Content',
},
}[locale]
}
// other props
/>;
export default async function Layout({
params,
children,
}: {
params: Promise<{ lang: string }>;
children: ReactNode;
}) {
const pageTree = source.pageTree[(await params).lang];

return <DocsLayout pageTree={pageTree}>{children}</DocsLayout>;
}
```

Note that without providing a locale code, it uses your default locale instead.
You can see [Source API](/docs/headless/source-api) for other usages.

### Writing Documents

see [Page Conventions](/docs/ui/page-conventions#internationalization) to learn how to organize your documents.

### Search

Configure i18n on your search solution.

- Built-in Search (Orama):
- For `createFromSource` and most languages, no further changes are needed.
- For special languages like Chinese & Japanese, they require additional config.
See [Orama I18n](/docs/headless/search/orama#internationalization) guide.
- Cloud Solutions (e.g. Algolia):
- They usually have official support for multilingual.

### Add Language Switch

To allow users changing their language, enable `i18n` on your layouts.
Expand Down
2 changes: 1 addition & 1 deletion examples/i18n/app/api/search/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createFromSource } from 'fumadocs-core/search/server';
import { createTokenizer } from '@orama/tokenizers/mandarin';
import { stopwords } from '@orama/stopwords/mandarin';

export const { GET, search } = createFromSource(source, undefined, {
export const { GET } = createFromSource(source, undefined, {
localeMap: {
// the prop name should be its locale code in your i18n config, (e.g. `cn`)
cn: {
Expand Down
12 changes: 12 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# fumadocs

## 0.0.6

### Patch Changes

- 969da26: Improve i18n api

## 0.0.5

### Patch Changes

- c8d9b08: support Next.js 15 i18n auto-config

## 0.0.4

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fumadocs/cli",
"version": "0.0.4",
"version": "0.0.6",
"description": "The CLI tool for Fumadocs",
"keywords": [
"NextJs",
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/plugins/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ export const i18nPlugin: Plugin = {
type: 'code',
title: 'page.tsx',
code: `
export default function Page({
export default async function Page({
params,
}: {
${picocolors.underline(picocolors.bold('params: { lang: string; slug?: string[] };'))}
${picocolors.underline(picocolors.bold('params: Promise<{ lang: string; slug?: string[] }>'))}
})
`.trim(),
},
Expand Down
6 changes: 4 additions & 2 deletions packages/cli/src/utils/i18n/transform-root-layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function runTransform(sourceFile: SourceFile): void {
.join('\n');

parent.setBodyText(
`<I18nProvider locale={params.lang} locales={[
`<I18nProvider locale={(await params).lang} locales={[
{ locale: 'en', name: 'English' }
]}>
${inner.trim()}
Expand All @@ -64,8 +64,10 @@ export function runTransform(sourceFile: SourceFile): void {
const func = sourceFile
.getDescendantsOfKind(SyntaxKind.FunctionDeclaration)
.find((v) => v.isDefaultExport());
func?.toggleModifier('async', true);

const param = func?.getParameters().at(0);
param?.setType(`{ params: { lang: string }, children: ReactNode }`);
param?.setType(`{ params: Promise<{ lang: string }>, children: ReactNode }`);
param?.set({
name: `{ params, children }`,
});
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/test/fixture/layout.out
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ const inter = Inter({
subsets: ['latin'],
});

export default function Layout({ params, children }: { params: { lang: string }, children: ReactNode }) {
export default async function Layout({ params, children }: { params: Promise<{ lang: string }>, children: ReactNode }) {
return (
<html lang="en" className={inter.className} suppressHydrationWarning>
<body>
<I18nProvider locale={params.lang} locales={[
<I18nProvider locale={(await params).lang} locales={[
{ locale: 'en', name: 'English' }
]}>
<RootProvider>{children}</RootProvider>
Expand Down
8 changes: 8 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# next-docs-zeta

## 14.6.6

## 14.6.5

### Patch Changes

- 969da26: Improve i18n api

## 14.6.4

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fumadocs-core",
"version": "14.6.4",
"version": "14.6.6",
"description": "The library for building a documentation website in Next.js",
"keywords": [
"NextJs",
Expand Down
15 changes: 10 additions & 5 deletions packages/core/src/search/client/static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import {
type RawData,
} from '@orama/orama';
import { type SortedResult } from '@/server';
import { searchSimple } from '@/search/search/simple';
import { searchAdvanced } from '@/search/search/advanced';
import { type advancedSchema } from '@/search/create-db';
import { type schema } from '@/search/create-db-simple';
import { searchSimple } from '@/search/orama/search/simple';
import { searchAdvanced } from '@/search/orama/search/advanced';
import {
type advancedSchema,
type simpleSchema,
} from '@/search/orama/create-db';

export interface StaticOptions {
/**
Expand Down Expand Up @@ -86,7 +88,10 @@ export function createStaticClient({

if (!cached) return [];
if (cached.type === 'simple')
return searchSimple(cached as unknown as Orama<typeof schema>, query);
return searchSimple(
cached as unknown as Orama<typeof simpleSchema>,
query,
);

return searchAdvanced(
cached.db as Orama<typeof advancedSchema>,
Expand Down
44 changes: 0 additions & 44 deletions packages/core/src/search/create-db-simple.ts

This file was deleted.

Loading
Loading