diff --git a/.changeset/young-grapes-jam.md b/.changeset/young-grapes-jam.md
new file mode 100644
index 000000000..f9f5bafbd
--- /dev/null
+++ b/.changeset/young-grapes-jam.md
@@ -0,0 +1,5 @@
+---
+'@fumadocs/cli': patch
+---
+
+Improve instructions in i18n plugin
diff --git a/apps/docs/content/docs/ui/index.mdx b/apps/docs/content/docs/ui/index.mdx
index 5290e1b6e..b6857fe1d 100644
--- a/apps/docs/content/docs/ui/index.mdx
+++ b/apps/docs/content/docs/ui/index.mdx
@@ -251,7 +251,7 @@ Make sure to read [Comparisons](/docs/ui/comparisons) if you're interested.
Fumadocs is designed with flexibility in mind.
You can use `fumadocs-core` as a headless UI library and bring your own styles.
-And `fumadocs-mdx` can be a useful content libraries like Content Collections, to handle MDX files easily in Next.js.
+And `fumadocs-mdx` can be a useful content library like Content Collections, to handle MDX files easily in Next.js.
### Use Cases
diff --git a/apps/docs/content/docs/ui/internationalization.mdx b/apps/docs/content/docs/ui/internationalization.mdx
index a038c8500..e3a45a5fd 100644
--- a/apps/docs/content/docs/ui/internationalization.mdx
+++ b/apps/docs/content/docs/ui/internationalization.mdx
@@ -20,9 +20,12 @@ You can setup i18n using Fumadocs CLI or update the configurations manually.
Initialize i18n with CLI.
```bash
+pnpm i @fumadocs/cli -D
pnpm fumadocs init i18n
```
+> This works only for the file structure generated by `create-fumadocs-app`, you can follow the manual installation for further needs.
+
## Manual Setup
Define the i18n configurations in a file, we will import it with `@/ilb/i18n` in this guide.
@@ -113,11 +116,7 @@ export default async function RootLayout({
{children}
@@ -129,7 +128,7 @@ export default async function RootLayout({
### Source
-For most cases, `source` object is the API to interact with your content source.
+`source` object is the API to interact with your content source.
For example, `source.getPage()` allows you to get a page with its slugs.
To get the page with appropriate locale, you need to pass the locale.
@@ -205,11 +204,20 @@ export const baseOptions: BaseLayoutProps = {
## Navigation
-Fumadocs will only handle i18n navigation for its own layouts (e.g. sidebar components),
-you have to re-create components like `` from `next/link` and `useParams` hook to auto attend the locale to `href`.
+Fumadocs will only handle navigation for its own layouts (e.g. sidebar components).
+For other links, you can use the `useParams` hook to get the locale from url, and attend it to `href`.
+
+```tsx
+import Link from 'next/link';
+import { useParams } from 'next/navigation';
+
+const { lang } = useParams();
+
+return This is a link;
+```
-In addition, the [`fumadocs-core/dynamic-link`](/docs/headless/components/link#dynamic-hrefs) component supports linking to dynamic hrefs, including the locale prefix.
-For Markdown/MDX content, you may use it instead of the default Link component:
+In addition, the [`fumadocs-core/dynamic-link`](/docs/headless/components/link#dynamic-hrefs) component supports dynamic hrefs, you can use it to attend the locale prefix.
+It is useful for Markdown/MDX content.
```mdx title="content.mdx"
import { DynamicLink } from 'fumadocs-core/dynamic-link';
diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts
index f7071a6dd..b141cc29a 100644
--- a/packages/cli/src/commands/init.ts
+++ b/packages/cli/src/commands/init.ts
@@ -47,6 +47,10 @@ export interface Plugin {
type: 'text';
text: string;
}
+ | {
+ type: 'title';
+ text: string;
+ }
)[]
>;
@@ -144,6 +148,7 @@ export async function init(plugin: Plugin, config: Config = {}): Promise {
if (value) {
await plugin.transform(ctx);
+
note(
`You can format the output with Prettier or other code formating tools
prettier . --write`,
@@ -165,5 +170,9 @@ prettier . --write`,
if (text.type === 'code') {
note(text.code, text.title);
}
+
+ if (text.type === 'title') {
+ log.step(text.text);
+ }
}
}
diff --git a/packages/cli/src/plugins/i18n.ts b/packages/cli/src/plugins/i18n.ts
index 3b37e5307..6660a90a9 100644
--- a/packages/cli/src/plugins/i18n.ts
+++ b/packages/cli/src/plugins/i18n.ts
@@ -1,5 +1,4 @@
import path from 'node:path';
-import picocolors from 'picocolors';
import { log } from '@clack/prompts';
import { type Plugin } from '@/commands/init';
import { generated } from '@/generated';
@@ -11,6 +10,7 @@ import { transformSourceI18n } from '@/utils/i18n/transform-source-i18n';
import { defaultConfig } from '@/config';
import { createEmptyProject } from '@/utils/typescript';
import { transformRootLayout } from '@/utils/i18n/transform-root-layout';
+import picocolors from 'picocolors';
export const i18nPlugin: Plugin = {
files: ({ src }) => ({
@@ -20,8 +20,19 @@ export const i18nPlugin: Plugin = {
dependencies: [],
instructions: () => [
{
- type: 'text',
- text: 'Make sure to update the params of page.tsx and route.ts (if necessary):',
+ type: 'title',
+ text: `1. Update the params of ${picocolors.bold('page.tsx')} and ${picocolors.bold('layout.tsx')}, and make them async if necessary.`,
+ },
+ {
+ type: 'code',
+ title: 'layout.tsx',
+ code: `
+export default async function Layout({
+ params,
+}: {
+ ${picocolors.underline(picocolors.bold('params: Promise<{ lang: string }>'))}
+})
+`.trim(),
},
{
type: 'code',
@@ -35,19 +46,12 @@ export default async function Page({
`.trim(),
},
{
- type: 'text',
- text: 'Update the usages to `source` with:',
- },
- {
- type: 'code',
- title: 'page.tsx',
- code: `const page = source.getPage(params.slug, params.lang);
-const pages = source.getPage(params.lang);`,
+ type: 'title',
+ text: '2. Update references to your `source` object',
},
{
- type: 'code',
- title: 'layout.tsx',
- code: `const tree = source.pageTree[params.lang];`,
+ type: 'text',
+ text: 'You can follow the instructions in https://fumadocs.vercel.app/docs/ui/internationalization#source section.',
},
],
async transform(ctx) {