update previous examples & add Tanstack Start i18n example

This commit is contained in:
Fuma Nama
2025-08-19 17:23:24 +08:00
parent 50eb07f51d
commit a217bdfe00
50 changed files with 691 additions and 142 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
import type { ReactNode } from 'react';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
export default async function Layout({
params,
@@ -1,13 +1,14 @@
import { source } from '@/lib/source';
import {
DocsPage,
DocsBody,
DocsTitle,
DocsDescription,
DocsPage,
DocsTitle,
} from 'fumadocs-ui/page';
import { notFound } from 'next/navigation';
import { metadataImage } from '@/lib/metadata';
import { getMDXComponents } from '@/mdx-components';
import type { Metadata } from 'next';
export default async function Page(props: {
params: Promise<{ lang: string; slug?: string[] }>;
@@ -35,7 +36,7 @@ export async function generateStaticParams() {
export async function generateMetadata(props: {
params: Promise<{ lang: string; slug?: string[] }>;
}) {
}): Promise<Metadata> {
const params = await props.params;
const page = source.getPage(params.slug, params.lang);
if (!page) notFound();
+1 -1
View File
@@ -1,7 +1,7 @@
import type { ReactNode } from 'react';
import { source } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
export default async function Layout({
params,
+21 -28
View File
@@ -2,11 +2,31 @@ import 'fumadocs-ui/style.css';
import { RootProvider } from 'fumadocs-ui/provider';
import { Inter } from 'next/font/google';
import type { ReactNode } from 'react';
import { defineI18nUI } from 'fumadocs-ui/i18n';
import { i18n } from '@/lib/i18n';
const inter = Inter({
subsets: ['latin'],
});
const { provider } = defineI18nUI(i18n, {
translations: {
en: {
displayName: 'English',
},
cn: {
displayName: 'Chinese',
toc: '目錄',
search: '搜尋文檔',
lastUpdate: '最後更新於',
searchNoResult: '沒有結果',
previousPage: '上一頁',
nextPage: '下一頁',
chooseLanguage: '選擇語言',
},
},
});
export default async function Layout({
params,
children,
@@ -24,34 +44,7 @@ export default async function Layout({
minHeight: '100vh',
}}
>
<RootProvider
i18n={{
locale: lang,
locales: [
{
name: 'English',
locale: 'en',
},
{
name: 'Chinese',
locale: 'cn',
},
],
translations: {
cn: {
toc: '目錄',
search: '搜尋文檔',
lastUpdate: '最後更新於',
searchNoResult: '沒有結果',
previousPage: '上一頁',
nextPage: '下一頁',
chooseLanguage: '選擇語言',
},
}[lang],
}}
>
{children}
</RootProvider>
<RootProvider i18n={provider(lang)}>{children}</RootProvider>
</body>
</html>
);
+3 -3
View File
@@ -1,6 +1,6 @@
import type { I18nConfig } from 'fumadocs-core/i18n';
import { defineI18n } from 'fumadocs-core/i18n';
export const i18n: I18nConfig = {
export const i18n = defineI18n({
defaultLanguage: 'en',
languages: ['en', 'cn'],
};
});
+2 -2
View File
@@ -1,11 +1,11 @@
import type { ReactNode } from 'react';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
export default function Layout({
children,
}: {
children: ReactNode;
}): React.ReactElement {
return <HomeLayout {...baseOptions}>{children}</HomeLayout>;
return <HomeLayout {...baseOptions()}>{children}</HomeLayout>;
}
+2 -2
View File
@@ -1,11 +1,11 @@
import { source } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import type { ReactNode } from 'react';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
export default function Layout({ children }: { children: ReactNode }) {
return (
<DocsLayout tree={source.pageTree} {...baseOptions}>
<DocsLayout tree={source.pageTree} {...baseOptions()}>
{children}
</DocsLayout>
);
-7
View File
@@ -1,7 +0,0 @@
import { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
export const baseOptions: BaseLayoutProps = {
nav: {
title: 'My App',
},
};
+9
View File
@@ -0,0 +1,9 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
export function baseOptions(): BaseLayoutProps {
return {
nav: {
title: 'My App',
},
};
}
+2 -2
View File
@@ -1,7 +1,7 @@
import type { ReactNode } from 'react';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
export default function Layout({ children }: { children: ReactNode }) {
return <HomeLayout {...baseOptions}>{children}</HomeLayout>;
return <HomeLayout {...baseOptions()}>{children}</HomeLayout>;
}
+2 -2
View File
@@ -1,11 +1,11 @@
import { source } from '@/lib/source';
import { DocsLayout } from 'fumadocs-ui/layouts/notebook';
import type { ReactNode } from 'react';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
export default function RootDocsLayout({ children }: { children: ReactNode }) {
return (
<DocsLayout tree={source.pageTree} {...baseOptions}>
<DocsLayout tree={source.pageTree} {...baseOptions()}>
{children}
</DocsLayout>
);
-8
View File
@@ -1,8 +0,0 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
import { Logo } from '@/app/logo';
export const baseOptions: BaseLayoutProps = {
nav: {
title: <Logo />,
},
};
+10
View File
@@ -0,0 +1,10 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
import { Logo } from '@/app/logo';
export function baseOptions(): BaseLayoutProps {
return {
nav: {
title: <Logo />,
},
};
}
+2 -2
View File
@@ -1,7 +1,7 @@
import type { ReactNode } from 'react';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
export default function Layout({ children }: { children: ReactNode }) {
return <HomeLayout {...baseOptions}>{children}</HomeLayout>;
return <HomeLayout {...baseOptions()}>{children}</HomeLayout>;
}
+2 -2
View File
@@ -1,11 +1,11 @@
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import type { ReactNode } from 'react';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
import { source } from '@/lib/source';
export default function Layout({ children }: { children: ReactNode }) {
return (
<DocsLayout tree={source.pageTree} {...baseOptions}>
<DocsLayout tree={source.pageTree} {...baseOptions()}>
{children}
</DocsLayout>
);
-21
View File
@@ -1,21 +0,0 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
/**
* Shared layout configurations
*
* you can customise layouts individually from:
* Home Layout: app/(home)/layout.tsx
* Docs Layout: app/docs/layout.tsx
*/
export const baseOptions: BaseLayoutProps = {
nav: {
title: 'Python Docs',
},
links: [
{
text: 'Documentation',
url: '/docs',
active: 'nested-url',
},
],
};
+16
View File
@@ -0,0 +1,16 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
export function baseOptions(): BaseLayoutProps {
return {
nav: {
title: 'Python Docs',
},
links: [
{
text: 'Documentation',
url: '/docs',
active: 'nested-url',
},
],
};
}
+23
View File
@@ -0,0 +1,23 @@
node_modules
package-lock.json
yarn.lock
.DS_Store
.cache
.env
.vercel
.output
.nitro
/build/
/api/
/server/build
/public/build# Sentry Config File
.env.sentry-build-plugin
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
.tanstack
src/routeTree.gen.ts
source.generated.ts
@@ -0,0 +1,4 @@
**/build
**/public
pnpm-lock.yaml
routeTree.gen.ts
@@ -0,0 +1,8 @@
---
title: 中文
description: 您的第一個文檔
---
## Hi 中文
Fumadocs 對 i18n 有良好的支持
@@ -0,0 +1,34 @@
---
title: Hello World
description: Your favourite docs framework.
icon: Rocket
---
Hey there! Fumadocs is a docs framework built for Next.js, but do you know it also works on Tanstack Start?
## Heading
Hello World!
<Cards>
<Card
title="Learn more about Tanstack Start"
href="https://tanstack.com/start"
/>
<Card title="Learn more about Fumadocs" href="https://fumadocs.vercel.app" />
</Cards>
### CodeBlock
```ts
console.log('Hello World');
```
#### Table
| Head | Description |
| ------------------------------- | ----------------------------------- |
| `hello` | Hello World |
| very **important** | Hey |
| _Surprisingly_ | Fumadocs |
| very long text that looks weird | hello world hello world hello world |
@@ -0,0 +1,12 @@
---
title: Test
description: This is another page
---
Hello World again!
## Installation
```npm
npm i fumadocs-core fumadocs-ui
```
+35
View File
@@ -0,0 +1,35 @@
{
"name": "example-tanstack-start-i18n",
"private": true,
"sideEffects": false,
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build && tsc --noEmit",
"start": "node .output/server/index.mjs"
},
"dependencies": {
"@orama/tokenizers": "^3.1.11",
"@tanstack/react-router": "^1.131.17",
"@tanstack/react-router-devtools": "^1.131.17",
"@tanstack/react-start": "^1.131.17",
"fumadocs-core": "workspace:*",
"fumadocs-mdx": "workspace:*",
"fumadocs-ui": "workspace:*",
"lucide-static": "^0.539.0",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"tailwind-merge": "^3.3.1",
"vite": "^7.1.2"
},
"devDependencies": {
"@tailwindcss/vite": "^4.1.12",
"@types/node": "^24.3.0",
"@types/react": "^19.1.10",
"@types/react-dom": "^19.1.7",
"@vitejs/plugin-react": "^5.0.0",
"tailwindcss": "^4.1.12",
"typescript": "^5.9.2",
"vite-tsconfig-paths": "^5.1.4"
}
}
@@ -0,0 +1,7 @@
import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
export const docs = defineDocs({
dir: 'content/docs',
});
export default defineConfig();
@@ -0,0 +1,31 @@
import { Link, useParams } from '@tanstack/react-router';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
export function NotFound() {
const { lang } = useParams({ from: '/$lang/' });
return (
<HomeLayout
nav={{
title: 'Tanstack Start',
}}
className="text-center py-32 justify-center"
>
<div className="flex flex-col items-center gap-4">
<h1 className="text-6xl font-bold text-fd-muted-foreground">404</h1>
<h2 className="text-2xl font-semibold">Page Not Found</h2>
<p className="text-fd-muted-foreground max-w-md">
The page you are looking for might have been removed, had its name
changed, or is temporarily unavailable.
</p>
<Link
to="/$lang"
params={{ lang }}
className="mt-4 px-4 py-2 rounded-lg bg-fd-primary text-fd-primary-foreground font-medium text-sm hover:opacity-90 transition-opacity"
>
Back to Home
</Link>
</div>
</HomeLayout>
);
}
@@ -0,0 +1,6 @@
import { defineI18n } from 'fumadocs-core/i18n';
export const i18n = defineI18n({
defaultLanguage: 'en',
languages: ['en', 'cn'],
});
@@ -0,0 +1,13 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
import { i18n } from '~/lib/i18n';
export function baseOptions(
locale: string = i18n.defaultLanguage,
): BaseLayoutProps {
return {
i18n,
nav: {
title: `Tanstack Start ${locale}`,
},
};
}
@@ -0,0 +1,18 @@
import { loader } from 'fumadocs-core/source';
import * as icons from 'lucide-static';
import { create, docs } from '../../source.generated';
import { i18n } from '~/lib/i18n';
export const source = loader({
source: await create.sourceAsync(docs.doc, docs.meta),
baseUrl: '/docs',
i18n,
// @ts-expect-error -- string
icon(icon) {
if (!icon) {
return;
}
if (icon in icons) return icons[icon as keyof typeof icons];
},
});
@@ -0,0 +1,18 @@
import { createRouter as createTanStackRouter } from '@tanstack/react-router';
import { routeTree } from './routeTree.gen';
import { NotFound } from '~/components/not-found';
export function createRouter() {
return createTanStackRouter({
routeTree,
defaultPreload: 'intent',
scrollRestoration: true,
defaultNotFoundComponent: NotFound,
});
}
declare module '@tanstack/react-router' {
interface Register {
router: ReturnType<typeof createRouter>;
}
}
@@ -0,0 +1,107 @@
import { createFileRoute, notFound } from '@tanstack/react-router';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { createServerFn } from '@tanstack/react-start';
import { source } from '~/lib/source';
import type { PageTree } from 'fumadocs-core/server';
import { useMemo } from 'react';
import { docs } from '../../../../source.generated';
import {
DocsBody,
DocsDescription,
DocsPage,
DocsTitle,
} from 'fumadocs-ui/page';
import defaultMdxComponents from 'fumadocs-ui/mdx';
import { createClientLoader } from 'fumadocs-mdx/runtime/vite';
import { baseOptions } from '~/lib/layout.shared';
export const Route = createFileRoute('/$lang/docs/$')({
component: Page,
loader: async ({ params }) => {
const data = await loader({
data: {
slugs: params._splat?.split('/') ?? [],
lang: params.lang,
},
});
await clientLoader.preload(data.path);
return data;
},
});
const loader = createServerFn({
method: 'GET',
})
.validator((params: { slugs: string[]; lang?: string }) => params)
.handler(async ({ data: { slugs, lang } }) => {
const page = source.getPage(slugs, lang);
if (!page) throw notFound();
return {
tree: source.getPageTree(lang) as object,
path: page.path,
};
});
const clientLoader = createClientLoader(docs.doc, {
id: 'docs',
component({ toc, frontmatter, default: MDX }) {
return (
<DocsPage toc={toc}>
<DocsTitle>{frontmatter.title}</DocsTitle>
<DocsDescription>{frontmatter.description}</DocsDescription>
<DocsBody>
<MDX
components={{
...defaultMdxComponents,
}}
/>
</DocsBody>
</DocsPage>
);
},
});
function Page() {
const { lang } = Route.useParams();
const data = Route.useLoaderData();
const Content = clientLoader.getComponent(data.path);
const tree = useMemo(
() => transformPageTree(data.tree as PageTree.Folder),
[data.tree],
);
return (
<DocsLayout {...baseOptions(lang)} tree={tree}>
<Content />
</DocsLayout>
);
}
function transformPageTree(tree: PageTree.Folder): PageTree.Folder {
function page(item: PageTree.Item) {
if (typeof item.icon !== 'string') return item;
return {
...item,
icon: (
<span
dangerouslySetInnerHTML={{
__html: item.icon,
}}
/>
),
};
}
return {
...tree,
index: tree.index ? page(tree.index) : undefined,
children: tree.children.map((item) => {
if (item.type === 'page') return page(item);
if (item.type === 'folder') return transformPageTree(item);
return item;
}),
};
}
@@ -0,0 +1,30 @@
import { createFileRoute, Link } from '@tanstack/react-router';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { baseOptions } from '~/lib/layout.shared';
export const Route = createFileRoute('/$lang/')({
component: Home,
});
function Home() {
const { lang } = Route.useParams();
return (
<HomeLayout
{...baseOptions(lang)}
className="text-center py-32 justify-center"
>
<h1 className="font-medium text-xl mb-4">Fumadocs on Tanstack Start.</h1>
<Link
to="/$lang/docs/$"
params={{
lang,
_splat: '',
}}
className="px-3 py-2 rounded-lg bg-fd-primary text-fd-primary-foreground font-medium text-sm mx-auto"
>
Open Docs
</Link>
</HomeLayout>
);
}
@@ -0,0 +1,71 @@
/// <reference types="vite/client" />
import {
createRootRoute,
HeadContent,
Outlet,
Scripts,
useParams,
} from '@tanstack/react-router';
import * as React from 'react';
import appCss from '~/styles/app.css?url';
import { RootProvider } from 'fumadocs-ui/provider/base';
import { TanstackProvider } from 'fumadocs-core/framework/tanstack';
import { defineI18nUI } from 'fumadocs-ui/i18n';
import { i18n } from '~/lib/i18n';
export const Route = createRootRoute({
head: () => ({
meta: [
{
charSet: 'utf-8',
},
{
name: 'viewport',
content: 'width=device-width, initial-scale=1',
},
{
title: 'Fumadocs on TanStack Start',
},
],
links: [{ rel: 'stylesheet', href: appCss }],
}),
component: RootComponent,
});
function RootComponent() {
return (
<RootDocument>
<Outlet />
</RootDocument>
);
}
const { provider } = defineI18nUI(i18n, {
translations: {
cn: {
displayName: 'Chinese',
search: 'Translated Content',
},
en: {
displayName: 'English',
},
},
});
function RootDocument({ children }: { children: React.ReactNode }) {
const { lang = i18n.defaultLanguage } = useParams({ strict: false });
return (
<html suppressHydrationWarning>
<head>
<HeadContent />
</head>
<body className="flex flex-col min-h-screen">
<TanstackProvider>
<RootProvider i18n={provider(lang)}>{children}</RootProvider>
</TanstackProvider>
<Scripts />
</body>
</html>
);
}
@@ -0,0 +1,17 @@
import { createServerFileRoute } from '@tanstack/react-start/server';
import { source } from '~/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';
import { createTokenizer } from '@orama/tokenizers/mandarin';
const server = createFromSource(source, {
localeMap: {
en: 'english',
cn: {
tokenizer: createTokenizer(),
},
},
});
export const ServerRoute = createServerFileRoute('/api/search').methods({
GET: async ({ request }) => server.GET(request),
});
@@ -0,0 +1,3 @@
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
@@ -0,0 +1,22 @@
{
"include": ["**/*.ts", "**/*.tsx"],
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Bundler",
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"isolatedModules": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"target": "ES2022",
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"~/*": ["./src/*"]
},
"noEmit": true
}
}
@@ -0,0 +1,23 @@
import react from '@vitejs/plugin-react';
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
import { defineConfig } from 'vite';
import tsConfigPaths from 'vite-tsconfig-paths';
import tailwindcss from '@tailwindcss/vite';
import mdx from 'fumadocs-mdx/vite';
export default defineConfig({
server: {
port: 3000,
},
plugins: [
mdx(await import('./source.config')),
tailwindcss(),
tsConfigPaths({
projects: ['./tsconfig.json'],
}),
tanstackStart({
customViteReactPlugin: true,
}),
react(),
],
});
+7 -2
View File
@@ -61,8 +61,13 @@
"types": "./dist/mdx-plugins/index.d.ts"
},
"./i18n": {
"import": "./dist/i18n/index.js",
"types": "./dist/i18n/index.d.ts"
"browser": "./dist/i18n/index.js",
"import": "./dist/i18n/index.server.js",
"types": "./dist/i18n/index.server.d.ts"
},
"./i18n/middleware": {
"import": "./dist/i18n/middleware.js",
"types": "./dist/i18n/middleware.d.ts"
},
"./highlight": {
"import": "./dist/highlight/index.js",
@@ -1,7 +1,7 @@
import type { ReactNode } from 'react';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
export default function Layout({ children }: { children: ReactNode }) {
return <HomeLayout {...baseOptions}>{children}</HomeLayout>;
return <HomeLayout {...baseOptions()}>{children}</HomeLayout>;
}
@@ -1,11 +1,11 @@
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import type { ReactNode } from 'react';
import { baseOptions } from '@/app/layout.config';
import { baseOptions } from '@/lib/layout.shared';
import { source } from '@/lib/source';
export default function Layout({ children }: { children: ReactNode }) {
return (
<DocsLayout tree={source.pageTree} {...baseOptions}>
<DocsLayout tree={source.pageTree} {...baseOptions()}>
{children}
</DocsLayout>
);
@@ -1,28 +0,0 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
/**
* Shared layout configurations
*
* you can customise layouts individually from:
* Home Layout: app/(home)/layout.tsx
* Docs Layout: app/docs/layout.tsx
*/
export const baseOptions: BaseLayoutProps = {
nav: {
title: (
<>
<svg
width="24"
height="24"
xmlns="http://www.w3.org/2000/svg"
aria-label="Logo"
>
<circle cx={12} cy={12} r={12} fill="currentColor" />
</svg>
My App
</>
),
},
// see https://fumadocs.dev/docs/ui/navigation/links
links: [],
};
@@ -0,0 +1,30 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
/**
* Shared layout configurations
*
* you can customise layouts individually from:
* Home Layout: app/(home)/layout.tsx
* Docs Layout: app/docs/layout.tsx
*/
export function baseOptions(): BaseLayoutProps {
return {
nav: {
title: (
<>
<svg
width="24"
height="24"
xmlns="http://www.w3.org/2000/svg"
aria-label="Logo"
>
<circle cx={12} cy={12} r={12} fill="currentColor" />
</svg>
My App
</>
),
},
// see https://fumadocs.dev/docs/ui/navigation/links
links: [],
};
}
@@ -6,7 +6,8 @@ import {
DocsPage,
DocsTitle,
} from 'fumadocs-ui/page';
import { source } from '@/source';
import { source } from '@/lib/source';
import { baseOptions } from '@/lib/layout.shared';
import { type PageTree } from 'fumadocs-core/server';
import defaultMdxComponents from 'fumadocs-ui/mdx';
import { docs } from '../../source.generated';
@@ -45,12 +46,7 @@ export default function Page(props: Route.ComponentProps) {
const Content = renderer[path];
return (
<DocsLayout
nav={{
title: 'React Router',
}}
tree={tree as PageTree.Root}
>
<DocsLayout {...baseOptions()} tree={tree as PageTree.Root}>
<Content />
</DocsLayout>
);
@@ -0,0 +1,9 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
export function baseOptions(): BaseLayoutProps {
return {
nav: {
title: 'React Router',
},
};
}
@@ -1,6 +1,7 @@
import type { Route } from './+types/home';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { Link } from 'react-router';
import { baseOptions } from '@/lib/layout.shared';
export function meta({}: Route.MetaArgs) {
return [
@@ -11,11 +12,7 @@ export function meta({}: Route.MetaArgs) {
export default function Home() {
return (
<HomeLayout
nav={{
title: 'React Router',
}}
>
<HomeLayout {...baseOptions()}>
<div className="p-4 flex flex-col items-center justify-center text-center flex-1">
<h1 className="text-xl font-bold mb-2">Fumadocs on React Router.</h1>
<p className="text-fd-muted-foreground mb-4">
@@ -0,0 +1,9 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
export function baseOptions(): BaseLayoutProps {
return {
nav: {
title: 'Tanstack Start',
},
};
}
@@ -13,6 +13,7 @@ import {
} from 'fumadocs-ui/page';
import defaultMdxComponents from 'fumadocs-ui/mdx';
import { createClientLoader } from 'fumadocs-mdx/runtime/vite';
import { baseOptions } from '~/lib/layout.shared';
export const Route = createFileRoute('/docs/$')({
component: Page,
@@ -66,12 +67,7 @@ function Page() {
);
return (
<DocsLayout
tree={tree}
nav={{
title: 'Fumadocs Tanstack',
}}
>
<DocsLayout {...baseOptions()} tree={tree}>
<Content />
</DocsLayout>
);
@@ -1,5 +1,6 @@
import { createFileRoute, Link } from '@tanstack/react-router';
import { HomeLayout } from 'fumadocs-ui/layouts/home';
import { baseOptions } from '~/lib/layout.shared';
export const Route = createFileRoute('/')({
component: Home,
@@ -7,12 +8,7 @@ export const Route = createFileRoute('/')({
function Home() {
return (
<HomeLayout
nav={{
title: 'Tanstack Start',
}}
className="text-center py-32 justify-center"
>
<HomeLayout {...baseOptions()} className="text-center py-32 justify-center">
<h1 className="font-medium text-xl mb-4">Fumadocs on Tanstack Start.</h1>
<Link
to="/docs/$"
+64
View File
@@ -776,6 +776,70 @@ importers:
specifier: ^5.1.4
version: 5.1.4([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
examples/tanstack-start-i18n:
dependencies:
'@orama/tokenizers':
specifier: ^3.1.11
version: 3.1.11
'@tanstack/react-router':
specifier: ^1.131.17
version: 1.131.17([email protected]([email protected]))([email protected])
'@tanstack/react-router-devtools':
specifier: ^1.131.17
version: 1.131.17(@tanstack/[email protected]([email protected]([email protected]))([email protected]))(@tanstack/[email protected])([email protected])([email protected]([email protected]))([email protected])([email protected])([email protected])
'@tanstack/react-start':
specifier: ^1.131.17
version: 1.131.17(@netlify/[email protected])(@tanstack/[email protected]([email protected]([email protected]))([email protected]))(@vitejs/[email protected]([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])))([email protected]([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))([email protected](@swc/[email protected])([email protected]))
fumadocs-core:
specifier: workspace:*
version: link:../../packages/core
fumadocs-mdx:
specifier: workspace:*
version: link:../../packages/mdx
fumadocs-ui:
specifier: workspace:*
version: link:../../packages/ui
lucide-static:
specifier: ^0.539.0
version: 0.539.0
react:
specifier: ^19.1.1
version: 19.1.1
react-dom:
specifier: ^19.1.1
version: 19.1.1([email protected])
tailwind-merge:
specifier: ^3.3.1
version: 3.3.1
vite:
specifier: ^7.1.2
version: 7.1.2(@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])
devDependencies:
'@tailwindcss/vite':
specifier: ^4.1.12
version: 4.1.12([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
'@types/node':
specifier: ^24.3.0
version: 24.3.0
'@types/react':
specifier: ^19.1.10
version: 19.1.10
'@types/react-dom':
specifier: ^19.1.7
version: 19.1.7(@types/[email protected])
'@vitejs/plugin-react':
specifier: ^5.0.0
version: 5.0.0([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
tailwindcss:
specifier: ^4.1.12
version: 4.1.12
typescript:
specifier: ^5.9.2
version: 5.9.2
vite-tsconfig-paths:
specifier: ^5.1.4
version: 5.1.4([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
examples/waku:
dependencies:
fumadocs-core: