create-fumadocs-app 15.6.5 → 15.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-J4NXLHNR.js → chunk-VLVSDHVS.js} +9 -9
- package/dist/create-app.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/template/react-router/app/docs/page.tsx +24 -26
- package/template/react-router/app/docs/search.ts +3 -10
- package/template/react-router/app/source.ts +3 -56
- package/template/react-router/package.json +8 -9
- package/template/react-router/react-router.config.ts +0 -4
- package/template/react-router/source.config.ts +7 -0
- package/template/react-router/vite.config.ts +3 -6
- package/template/tanstack-start/content/test.mdx +2 -0
- package/template/tanstack-start/package.json +13 -14
- package/template/tanstack-start/source.config.ts +7 -0
- package/template/tanstack-start/src/lib/source.ts +3 -53
- package/template/tanstack-start/src/router.tsx +1 -1
- package/template/tanstack-start/src/routes/api/search.ts +2 -10
- package/template/tanstack-start/src/routes/docs/$.tsx +62 -57
- package/template/tanstack-start/vite.config.ts +3 -1
- /package/template/tanstack-start/src/components/{NotFound.tsx → not-found.tsx} +0 -0
|
@@ -59,7 +59,7 @@ async function tryGitInit(cwd2) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// src/versions.js
|
|
62
|
-
var versions = { "fumadocs-core": "15.6.
|
|
62
|
+
var versions = { "fumadocs-core": "15.6.6", "fumadocs-ui": "15.6.6", "fumadocs-mdx": "11.7.1", "@fumadocs/mdx-remote": "1.4.0", "@fumadocs/content-collections": "1.2.1" };
|
|
63
63
|
|
|
64
64
|
// ../create-app-versions/package.json
|
|
65
65
|
var package_default = {
|
|
@@ -72,25 +72,25 @@ var package_default = {
|
|
|
72
72
|
"@content-collections/core": "^0.10.0",
|
|
73
73
|
"@content-collections/mdx": "^0.2.2",
|
|
74
74
|
"@content-collections/next": "^0.2.6",
|
|
75
|
-
"@react-router/dev": "^7.7.
|
|
76
|
-
"@react-router/node": "^7.7.
|
|
77
|
-
"@react-router/serve": "^7.7.
|
|
75
|
+
"@react-router/dev": "^7.7.1",
|
|
76
|
+
"@react-router/node": "^7.7.1",
|
|
77
|
+
"@react-router/serve": "^7.7.1",
|
|
78
78
|
"@tailwindcss/postcss": "^4.1.11",
|
|
79
79
|
"@tailwindcss/vite": "^4.1.11",
|
|
80
|
-
"@tanstack/react-router": "^1.
|
|
81
|
-
"@tanstack/react-start": "^1.
|
|
80
|
+
"@tanstack/react-router": "^1.129.0",
|
|
81
|
+
"@tanstack/react-start": "^1.129.0",
|
|
82
82
|
"@types/mdx": "^2.0.13",
|
|
83
|
-
"@types/node": "24.0
|
|
83
|
+
"@types/node": "24.1.0",
|
|
84
84
|
"@types/react": "^19.1.8",
|
|
85
85
|
"@types/react-dom": "^19.1.6",
|
|
86
86
|
"@vitejs/plugin-react": "^4.7.0",
|
|
87
87
|
"gray-matter": "^4.0.3",
|
|
88
88
|
isbot: "^5.1.28",
|
|
89
|
-
next: "15.4.
|
|
89
|
+
next: "15.4.4",
|
|
90
90
|
postcss: "^8.5.6",
|
|
91
91
|
react: "^19.1.0",
|
|
92
92
|
"react-dom": "^19.1.0",
|
|
93
|
-
"react-router": "^7.7.
|
|
93
|
+
"react-router": "^7.7.1",
|
|
94
94
|
"react-router-devtools": "^5.0.6",
|
|
95
95
|
shiki: "^3.8.1",
|
|
96
96
|
tailwindcss: "^4.1.11",
|
package/dist/create-app.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-fumadocs-app",
|
|
3
|
-
"version": "15.6.
|
|
3
|
+
"version": "15.6.6",
|
|
4
4
|
"description": "Create a new documentation site with Fumadocs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NextJs",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/cross-spawn": "^6.0.6",
|
|
31
|
-
"@types/node": "24.0
|
|
31
|
+
"@types/node": "24.1.0",
|
|
32
32
|
"tinyglobby": "^0.2.14",
|
|
33
33
|
"eslint-config-custom": "0.0.0",
|
|
34
34
|
"tsconfig": "0.0.0"
|
|
@@ -7,36 +7,42 @@ import {
|
|
|
7
7
|
DocsTitle,
|
|
8
8
|
} from 'fumadocs-ui/page';
|
|
9
9
|
import { source } from '@/source';
|
|
10
|
+
import { type PageTree } from 'fumadocs-core/server';
|
|
10
11
|
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import { createCompiler } from '@fumadocs/mdx-remote';
|
|
14
|
-
import * as path from 'node:path';
|
|
15
|
-
|
|
16
|
-
const compiler = createCompiler({
|
|
17
|
-
development: false,
|
|
18
|
-
});
|
|
12
|
+
import { docs } from '../../source.generated';
|
|
13
|
+
import { toClientRenderer } from 'fumadocs-mdx/runtime/vite';
|
|
19
14
|
|
|
20
15
|
export async function loader({ params }: Route.LoaderArgs) {
|
|
21
16
|
const slugs = params['*'].split('/').filter((v) => v.length > 0);
|
|
22
17
|
const page = source.getPage(slugs);
|
|
23
18
|
if (!page) throw new Response('Not found', { status: 404 });
|
|
24
19
|
|
|
25
|
-
const compiled = await compiler.compileFile({
|
|
26
|
-
path: path.resolve('content/docs', page.path),
|
|
27
|
-
value: page.data.content,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
20
|
return {
|
|
31
|
-
page,
|
|
32
|
-
compiled: compiled.toString(),
|
|
21
|
+
path: page.path,
|
|
33
22
|
tree: source.pageTree,
|
|
34
23
|
};
|
|
35
24
|
}
|
|
36
25
|
|
|
26
|
+
const renderer = toClientRenderer(
|
|
27
|
+
docs.doc,
|
|
28
|
+
({ toc, default: Mdx, frontmatter }) => {
|
|
29
|
+
return (
|
|
30
|
+
<DocsPage toc={toc}>
|
|
31
|
+
<title>{frontmatter.title}</title>
|
|
32
|
+
<meta name="description" content={frontmatter.description} />
|
|
33
|
+
<DocsTitle>{frontmatter.title}</DocsTitle>
|
|
34
|
+
<DocsDescription>{frontmatter.description}</DocsDescription>
|
|
35
|
+
<DocsBody>
|
|
36
|
+
<Mdx components={{ ...defaultMdxComponents }} />
|
|
37
|
+
</DocsBody>
|
|
38
|
+
</DocsPage>
|
|
39
|
+
);
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
|
|
37
43
|
export default function Page(props: Route.ComponentProps) {
|
|
38
|
-
const {
|
|
39
|
-
const
|
|
44
|
+
const { tree, path } = props.loaderData;
|
|
45
|
+
const Content = renderer[path];
|
|
40
46
|
|
|
41
47
|
return (
|
|
42
48
|
<DocsLayout
|
|
@@ -45,15 +51,7 @@ export default function Page(props: Route.ComponentProps) {
|
|
|
45
51
|
}}
|
|
46
52
|
tree={tree as PageTree.Root}
|
|
47
53
|
>
|
|
48
|
-
<
|
|
49
|
-
<meta name="description" content={page.data.description} />
|
|
50
|
-
<DocsPage toc={toc}>
|
|
51
|
-
<DocsTitle>{page.data.title}</DocsTitle>
|
|
52
|
-
<DocsDescription>{page.data.description}</DocsDescription>
|
|
53
|
-
<DocsBody>
|
|
54
|
-
<Mdx components={defaultMdxComponents} />
|
|
55
|
-
</DocsBody>
|
|
56
|
-
</DocsPage>
|
|
54
|
+
<Content />
|
|
57
55
|
</DocsLayout>
|
|
58
56
|
);
|
|
59
57
|
}
|
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import type { Route } from './+types/search';
|
|
2
|
-
import {
|
|
2
|
+
import { createFromSource } from 'fumadocs-core/search/server';
|
|
3
3
|
import { source } from '@/source';
|
|
4
|
-
import { structure } from 'fumadocs-core/mdx-plugins';
|
|
5
4
|
|
|
6
|
-
const server =
|
|
7
|
-
|
|
8
|
-
id: page.url,
|
|
9
|
-
url: page.url,
|
|
10
|
-
title: page.data.title ?? '',
|
|
11
|
-
description: page.data.description,
|
|
12
|
-
structuredData: structure(page.data.content),
|
|
13
|
-
})),
|
|
5
|
+
const server = createFromSource(source, {
|
|
6
|
+
language: 'english',
|
|
14
7
|
});
|
|
15
8
|
|
|
16
9
|
export async function loader({ request }: Route.LoaderArgs) {
|
|
@@ -1,60 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type MetaData,
|
|
4
|
-
type PageData,
|
|
5
|
-
type Source,
|
|
6
|
-
type VirtualFile,
|
|
7
|
-
} from 'fumadocs-core/source';
|
|
8
|
-
import matter from 'gray-matter';
|
|
9
|
-
import * as path from 'node:path';
|
|
10
|
-
|
|
11
|
-
const files = Object.entries(
|
|
12
|
-
import.meta.glob<true, 'raw'>('/content/docs/**/*', {
|
|
13
|
-
eager: true,
|
|
14
|
-
query: '?raw',
|
|
15
|
-
import: 'default',
|
|
16
|
-
}),
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
const virtualFiles: VirtualFile[] = files.flatMap(([file, content]) => {
|
|
20
|
-
const ext = path.extname(file);
|
|
21
|
-
const virtualPath = path.relative(
|
|
22
|
-
'content/docs',
|
|
23
|
-
path.join(process.cwd(), file),
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
if (ext === '.mdx' || ext === '.md') {
|
|
27
|
-
const parsed = matter(content);
|
|
28
|
-
|
|
29
|
-
return {
|
|
30
|
-
type: 'page',
|
|
31
|
-
path: virtualPath,
|
|
32
|
-
data: {
|
|
33
|
-
...parsed.data,
|
|
34
|
-
content: parsed.content,
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (ext === '.json') {
|
|
40
|
-
return {
|
|
41
|
-
type: 'meta',
|
|
42
|
-
path: virtualPath,
|
|
43
|
-
data: JSON.parse(content),
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return [];
|
|
48
|
-
});
|
|
1
|
+
import { loader } from 'fumadocs-core/source';
|
|
2
|
+
import { create, docs } from '../source.generated';
|
|
49
3
|
|
|
50
4
|
export const source = loader({
|
|
51
|
-
source:
|
|
52
|
-
files: virtualFiles,
|
|
53
|
-
} as Source<{
|
|
54
|
-
pageData: PageData & {
|
|
55
|
-
content: string;
|
|
56
|
-
};
|
|
57
|
-
metaData: MetaData;
|
|
58
|
-
}>,
|
|
5
|
+
source: await create.sourceAsync(docs.doc, docs.meta),
|
|
59
6
|
baseUrl: '/docs',
|
|
60
7
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
+
"name": "example-react-router",
|
|
2
3
|
"private": true,
|
|
3
4
|
"type": "module",
|
|
4
5
|
"scripts": {
|
|
@@ -8,28 +9,26 @@
|
|
|
8
9
|
"typecheck": "react-router typegen && tsc"
|
|
9
10
|
},
|
|
10
11
|
"dependencies": {
|
|
11
|
-
"@
|
|
12
|
-
"@react-router/
|
|
13
|
-
"@react-router/serve": "^7.6.3",
|
|
12
|
+
"@react-router/node": "^7.7.0",
|
|
13
|
+
"@react-router/serve": "^7.7.0",
|
|
14
14
|
"fumadocs-core": "workspace:*",
|
|
15
|
+
"fumadocs-mdx": "workspace:*",
|
|
15
16
|
"fumadocs-ui": "workspace:*",
|
|
16
|
-
"gray-matter": "^4.0.3",
|
|
17
17
|
"isbot": "^5.1.28",
|
|
18
18
|
"react": "^19.1.0",
|
|
19
19
|
"react-dom": "^19.1.0",
|
|
20
|
-
"react-router": "^7.
|
|
21
|
-
"shiki": "^3.8.0"
|
|
20
|
+
"react-router": "^7.7.0"
|
|
22
21
|
},
|
|
23
22
|
"devDependencies": {
|
|
24
|
-
"@react-router/dev": "^7.
|
|
23
|
+
"@react-router/dev": "^7.7.0",
|
|
25
24
|
"@tailwindcss/vite": "^4.1.11",
|
|
26
|
-
"@types/node": "^24.0.
|
|
25
|
+
"@types/node": "^24.0.15",
|
|
27
26
|
"@types/react": "^19.1.8",
|
|
28
27
|
"@types/react-dom": "^19.1.6",
|
|
29
28
|
"react-router-devtools": "^5.0.6",
|
|
30
29
|
"tailwindcss": "^4.1.11",
|
|
31
30
|
"typescript": "^5.8.3",
|
|
32
|
-
"vite": "^7.0.
|
|
31
|
+
"vite": "^7.0.5",
|
|
33
32
|
"vite-tsconfig-paths": "^5.1.4"
|
|
34
33
|
}
|
|
35
34
|
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import type { Config } from '@react-router/dev/config';
|
|
2
|
-
import { source } from './app/source';
|
|
3
2
|
|
|
4
3
|
export default {
|
|
5
4
|
ssr: true,
|
|
6
|
-
async prerender({ getStaticPaths }) {
|
|
7
|
-
return [...getStaticPaths(), ...source.getPages().map((page) => page.url)];
|
|
8
|
-
},
|
|
9
5
|
} satisfies Config;
|
|
@@ -2,12 +2,9 @@ import { reactRouter } from '@react-router/dev/vite';
|
|
|
2
2
|
import tailwindcss from '@tailwindcss/vite';
|
|
3
3
|
import { defineConfig } from 'vite';
|
|
4
4
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
5
|
+
import mdx from 'fumadocs-mdx/vite';
|
|
6
|
+
import * as MdxConfig from './source.config';
|
|
5
7
|
|
|
6
8
|
export default defineConfig({
|
|
7
|
-
|
|
8
|
-
rollupOptions: {
|
|
9
|
-
external: ['shiki'],
|
|
10
|
-
},
|
|
11
|
-
},
|
|
12
|
-
plugins: [tailwindcss(), reactRouter(), tsconfigPaths()],
|
|
9
|
+
plugins: [mdx(MdxConfig), tailwindcss(), reactRouter(), tsconfigPaths()],
|
|
13
10
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
+
"name": "example-tanstack-start",
|
|
2
3
|
"private": true,
|
|
3
4
|
"sideEffects": false,
|
|
4
5
|
"type": "module",
|
|
@@ -8,28 +9,26 @@
|
|
|
8
9
|
"start": "node .output/server/index.mjs"
|
|
9
10
|
},
|
|
10
11
|
"dependencies": {
|
|
11
|
-
"@
|
|
12
|
-
"@tanstack/react-router": "^1.
|
|
13
|
-
"@tanstack/react-
|
|
14
|
-
"@tanstack/react-start": "^1.128.1",
|
|
12
|
+
"@tanstack/react-router": "^1.129.0",
|
|
13
|
+
"@tanstack/react-router-devtools": "^1.129.0",
|
|
14
|
+
"@tanstack/react-start": "^1.129.0",
|
|
15
15
|
"fumadocs-core": "workspace:*",
|
|
16
|
+
"fumadocs-mdx": "workspace:*",
|
|
16
17
|
"fumadocs-ui": "workspace:*",
|
|
17
|
-
"gray-matter": "^4.0.3",
|
|
18
18
|
"lucide-static": "^0.525.0",
|
|
19
|
-
"react": "^19.
|
|
20
|
-
"react-dom": "^19.
|
|
19
|
+
"react": "^19.0.0",
|
|
20
|
+
"react-dom": "^19.0.0",
|
|
21
21
|
"tailwind-merge": "^3.3.1",
|
|
22
|
-
"vite": "^7.0.5"
|
|
23
|
-
"zod": "^4.0.5"
|
|
22
|
+
"vite": "^7.0.5"
|
|
24
23
|
},
|
|
25
24
|
"devDependencies": {
|
|
26
25
|
"@tailwindcss/vite": "^4.1.11",
|
|
27
|
-
"@types/node": "^24.0.
|
|
28
|
-
"@types/react": "^19.
|
|
29
|
-
"@types/react-dom": "^19.
|
|
30
|
-
"@vitejs/plugin-react": "^4.
|
|
26
|
+
"@types/node": "^24.0.15",
|
|
27
|
+
"@types/react": "^19.0.8",
|
|
28
|
+
"@types/react-dom": "^19.0.3",
|
|
29
|
+
"@vitejs/plugin-react": "^4.7.0",
|
|
31
30
|
"tailwindcss": "^4.1.11",
|
|
32
|
-
"typescript": "^5.
|
|
31
|
+
"typescript": "^5.7.2",
|
|
33
32
|
"vite-tsconfig-paths": "^5.1.4"
|
|
34
33
|
}
|
|
35
34
|
}
|
|
@@ -1,59 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loader,
|
|
3
|
-
type MetaData,
|
|
4
|
-
type PageData,
|
|
5
|
-
type Source,
|
|
6
|
-
type VirtualFile,
|
|
7
|
-
} from 'fumadocs-core/source';
|
|
8
|
-
import matter from 'gray-matter';
|
|
9
|
-
import * as path from 'node:path';
|
|
1
|
+
import { loader } from 'fumadocs-core/source';
|
|
10
2
|
import * as icons from 'lucide-static';
|
|
11
|
-
|
|
12
|
-
const files = Object.entries(
|
|
13
|
-
import.meta.glob<true, 'raw'>('/content/**/*', {
|
|
14
|
-
eager: true,
|
|
15
|
-
query: '?raw',
|
|
16
|
-
import: 'default',
|
|
17
|
-
}),
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
const virtualFiles: VirtualFile[] = files.flatMap(([file, content]) => {
|
|
21
|
-
const ext = path.extname(file);
|
|
22
|
-
const virtualPath = path.relative('content', path.join(process.cwd(), file));
|
|
23
|
-
|
|
24
|
-
if (ext === '.mdx' || ext === '.md') {
|
|
25
|
-
const parsed = matter(content);
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
type: 'page',
|
|
29
|
-
path: virtualPath,
|
|
30
|
-
data: {
|
|
31
|
-
...parsed.data,
|
|
32
|
-
content: parsed.content,
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (ext === '.json') {
|
|
38
|
-
return {
|
|
39
|
-
type: 'meta',
|
|
40
|
-
path: virtualPath,
|
|
41
|
-
data: JSON.parse(content),
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return [];
|
|
46
|
-
});
|
|
3
|
+
import { create, docs } from '../../source.generated';
|
|
47
4
|
|
|
48
5
|
export const source = loader({
|
|
49
|
-
source:
|
|
50
|
-
files: virtualFiles,
|
|
51
|
-
} as Source<{
|
|
52
|
-
pageData: PageData & {
|
|
53
|
-
content: string;
|
|
54
|
-
};
|
|
55
|
-
metaData: MetaData;
|
|
56
|
-
}>,
|
|
6
|
+
source: await create.sourceAsync(docs.doc, docs.meta),
|
|
57
7
|
baseUrl: '/docs',
|
|
58
8
|
// @ts-expect-error -- string
|
|
59
9
|
icon(icon) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRouter as createTanStackRouter } from '@tanstack/react-router';
|
|
2
2
|
import { routeTree } from './routeTree.gen';
|
|
3
|
-
import { NotFound } from '
|
|
3
|
+
import { NotFound } from '~/components/not-found';
|
|
4
4
|
|
|
5
5
|
export function createRouter() {
|
|
6
6
|
return createTanStackRouter({
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import { createServerFileRoute } from '@tanstack/react-start/server';
|
|
2
|
-
import { createSearchAPI } from 'fumadocs-core/search/server';
|
|
3
2
|
import { source } from '~/lib/source';
|
|
4
|
-
import {
|
|
3
|
+
import { createFromSource } from 'fumadocs-core/search/server';
|
|
5
4
|
|
|
6
|
-
const server =
|
|
7
|
-
indexes: source.getPages().map((page) => ({
|
|
8
|
-
id: page.url,
|
|
9
|
-
url: page.url,
|
|
10
|
-
title: page.data.title!,
|
|
11
|
-
structuredData: structure(page.data.content),
|
|
12
|
-
})),
|
|
13
|
-
});
|
|
5
|
+
const server = createFromSource(source);
|
|
14
6
|
|
|
15
7
|
export const ServerRoute = createServerFileRoute('/api/search').methods({
|
|
16
8
|
GET: async ({ request }) => server.GET(request),
|
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import { createFileRoute, notFound } from '@tanstack/react-router';
|
|
2
|
-
import { executeMdxSync } from '@fumadocs/mdx-remote/client';
|
|
3
2
|
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
|
3
|
+
import { createServerFn } from '@tanstack/react-start';
|
|
4
|
+
import { source } from '~/lib/source';
|
|
5
|
+
import type { PageTree } from 'fumadocs-core/server';
|
|
6
|
+
import { useMemo } from 'react';
|
|
7
|
+
import { docs } from '../../../source.generated';
|
|
4
8
|
import {
|
|
5
9
|
DocsBody,
|
|
6
10
|
DocsDescription,
|
|
7
11
|
DocsPage,
|
|
8
12
|
DocsTitle,
|
|
9
13
|
} from 'fumadocs-ui/page';
|
|
10
|
-
import { createServerFn } from '@tanstack/react-start';
|
|
11
|
-
import { createCompiler } from '@fumadocs/mdx-remote';
|
|
12
|
-
import { source } from '~/lib/source';
|
|
13
|
-
import path from 'node:path';
|
|
14
14
|
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
|
15
|
-
import
|
|
16
|
-
import { useMemo } from 'react';
|
|
17
|
-
|
|
18
|
-
const compiler = createCompiler();
|
|
15
|
+
import { createClientLoader } from 'fumadocs-mdx/runtime/vite';
|
|
19
16
|
|
|
20
17
|
export const Route = createFileRoute('/docs/$')({
|
|
21
18
|
component: Page,
|
|
22
19
|
loader: async ({ params }) => {
|
|
23
|
-
const
|
|
24
|
-
|
|
20
|
+
const data = await loader({ data: params._splat?.split('/') ?? [] });
|
|
21
|
+
await clientLoader.preload(data.path);
|
|
22
|
+
return data;
|
|
25
23
|
},
|
|
26
24
|
});
|
|
27
25
|
|
|
@@ -34,48 +32,38 @@ const loader = createServerFn({
|
|
|
34
32
|
const page = source.getPage(slugs);
|
|
35
33
|
if (!page) throw notFound();
|
|
36
34
|
|
|
37
|
-
const { content, ...rest } = page.data;
|
|
38
|
-
const compiled = await compiler.compileFile({
|
|
39
|
-
path: path.resolve('content', page.path),
|
|
40
|
-
value: content,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
35
|
return {
|
|
44
36
|
tree: source.pageTree as object,
|
|
45
|
-
|
|
46
|
-
compiled: compiled.toString(),
|
|
37
|
+
path: page.path,
|
|
47
38
|
};
|
|
48
39
|
});
|
|
49
40
|
|
|
41
|
+
const clientLoader = createClientLoader(docs.doc, {
|
|
42
|
+
id: 'docs',
|
|
43
|
+
component({ toc, frontmatter, default: MDX }) {
|
|
44
|
+
return (
|
|
45
|
+
<DocsPage toc={toc}>
|
|
46
|
+
<DocsTitle>{frontmatter.title}</DocsTitle>
|
|
47
|
+
<DocsDescription>{frontmatter.description}</DocsDescription>
|
|
48
|
+
<DocsBody>
|
|
49
|
+
<MDX
|
|
50
|
+
components={{
|
|
51
|
+
...defaultMdxComponents,
|
|
52
|
+
}}
|
|
53
|
+
/>
|
|
54
|
+
</DocsBody>
|
|
55
|
+
</DocsPage>
|
|
56
|
+
);
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
50
60
|
function Page() {
|
|
51
61
|
const data = Route.useLoaderData();
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
tree,
|
|
56
|
-
|
|
57
|
-
const result = executeMdxSync(data.compiled);
|
|
58
|
-
|
|
59
|
-
function traverse(folder: PageTree.Folder | PageTree.Root) {
|
|
60
|
-
for (const node of folder.children) {
|
|
61
|
-
if (node.type === 'page' && typeof node.icon === 'string') {
|
|
62
|
-
node.icon = (
|
|
63
|
-
<span
|
|
64
|
-
dangerouslySetInnerHTML={{
|
|
65
|
-
__html: node.icon,
|
|
66
|
-
}}
|
|
67
|
-
/>
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (node.type === 'folder') traverse(node);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const tree = structuredClone(data.tree) as PageTree.Root;
|
|
76
|
-
traverse(tree);
|
|
77
|
-
return { ...result, tree };
|
|
78
|
-
}, [data]);
|
|
62
|
+
const Content = clientLoader.getComponent(data.path);
|
|
63
|
+
const tree = useMemo(
|
|
64
|
+
() => transformPageTree(data.tree as PageTree.Folder),
|
|
65
|
+
[data.tree],
|
|
66
|
+
);
|
|
79
67
|
|
|
80
68
|
return (
|
|
81
69
|
<DocsLayout
|
|
@@ -84,17 +72,34 @@ function Page() {
|
|
|
84
72
|
title: 'Fumadocs Tanstack',
|
|
85
73
|
}}
|
|
86
74
|
>
|
|
87
|
-
<
|
|
88
|
-
<DocsTitle>{data.title}</DocsTitle>
|
|
89
|
-
<DocsDescription>{data.description}</DocsDescription>
|
|
90
|
-
<DocsBody>
|
|
91
|
-
<MDX
|
|
92
|
-
components={{
|
|
93
|
-
...defaultMdxComponents,
|
|
94
|
-
}}
|
|
95
|
-
/>
|
|
96
|
-
</DocsBody>
|
|
97
|
-
</DocsPage>
|
|
75
|
+
<Content />
|
|
98
76
|
</DocsLayout>
|
|
99
77
|
);
|
|
100
78
|
}
|
|
79
|
+
|
|
80
|
+
function transformPageTree(tree: PageTree.Folder): PageTree.Folder {
|
|
81
|
+
function page(item: PageTree.Item) {
|
|
82
|
+
if (typeof item.icon !== 'string') return item;
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
...item,
|
|
86
|
+
icon: (
|
|
87
|
+
<span
|
|
88
|
+
dangerouslySetInnerHTML={{
|
|
89
|
+
__html: item.icon,
|
|
90
|
+
}}
|
|
91
|
+
/>
|
|
92
|
+
),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
...tree,
|
|
98
|
+
index: tree.index ? page(tree.index) : undefined,
|
|
99
|
+
children: tree.children.map((item) => {
|
|
100
|
+
if (item.type === 'page') return page(item);
|
|
101
|
+
if (item.type === 'folder') return transformPageTree(item);
|
|
102
|
+
return item;
|
|
103
|
+
}),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import react from '@vitejs/plugin-react';
|
|
1
2
|
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
|
|
2
3
|
import { defineConfig } from 'vite';
|
|
3
4
|
import tsConfigPaths from 'vite-tsconfig-paths';
|
|
4
5
|
import tailwindcss from '@tailwindcss/vite';
|
|
5
|
-
import
|
|
6
|
+
import mdx from 'fumadocs-mdx/vite';
|
|
6
7
|
|
|
7
8
|
export default defineConfig({
|
|
8
9
|
server: {
|
|
9
10
|
port: 3000,
|
|
10
11
|
},
|
|
11
12
|
plugins: [
|
|
13
|
+
mdx(await import('./source.config')),
|
|
12
14
|
tailwindcss(),
|
|
13
15
|
tsConfigPaths({
|
|
14
16
|
projects: ['./tsconfig.json'],
|
|
File without changes
|