create-fumadocs-app 15.6.3 → 15.6.5
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 +330 -0
- package/dist/create-app.d.ts +5 -3
- package/dist/create-app.js +5 -3
- package/dist/index.js +84 -38
- package/package.json +5 -4
- package/template/react-router/app/docs/page.tsx +4 -8
- package/template/react-router/app/routes/home.tsx +2 -3
- package/template/react-router/content/docs/test.mdx +20 -4
- package/template/react-router/package.json +35 -0
- package/template/tanstack-start/content/{docs/index.mdx → index.mdx} +2 -3
- package/template/tanstack-start/content/test.mdx +10 -0
- package/template/tanstack-start/example.gitignore +8 -2
- package/template/tanstack-start/package.json +35 -0
- package/template/tanstack-start/src/components/NotFound.tsx +28 -0
- package/template/tanstack-start/{lib → src/lib}/source.ts +17 -21
- package/template/tanstack-start/{app → src}/router.tsx +3 -0
- package/template/tanstack-start/{app → src}/routes/__root.tsx +4 -3
- package/template/tanstack-start/{app → src}/routes/api/search.ts +5 -8
- package/template/tanstack-start/{app → src}/routes/docs/$.tsx +47 -18
- package/template/tanstack-start/{app → src}/routes/index.tsx +4 -1
- package/template/tanstack-start/tsconfig.json +14 -7
- package/template/tanstack-start/vite.config.ts +21 -0
- package/dist/chunk-FAFA6275.js +0 -380
- package/template/tanstack-start/app/api.ts +0 -6
- package/template/tanstack-start/app/client.tsx +0 -7
- package/template/tanstack-start/app/ssr.tsx +0 -13
- package/template/tanstack-start/app.config.ts +0 -43
- /package/template/tanstack-start/{app → src/styles}/app.css +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"private": true,
|
|
3
|
+
"sideEffects": false,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite dev",
|
|
7
|
+
"build": "vite build && tsc --noEmit",
|
|
8
|
+
"start": "node .output/server/index.mjs"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@fumadocs/mdx-remote": "workspace:*",
|
|
12
|
+
"@tanstack/react-router": "^1.128.0",
|
|
13
|
+
"@tanstack/react-router-devtools": "^1.128.0",
|
|
14
|
+
"@tanstack/react-start": "^1.128.1",
|
|
15
|
+
"fumadocs-core": "workspace:*",
|
|
16
|
+
"fumadocs-ui": "workspace:*",
|
|
17
|
+
"gray-matter": "^4.0.3",
|
|
18
|
+
"lucide-static": "^0.525.0",
|
|
19
|
+
"react": "^19.1.0",
|
|
20
|
+
"react-dom": "^19.1.0",
|
|
21
|
+
"tailwind-merge": "^3.3.1",
|
|
22
|
+
"vite": "^7.0.5",
|
|
23
|
+
"zod": "^4.0.5"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@tailwindcss/vite": "^4.1.11",
|
|
27
|
+
"@types/node": "^24.0.14",
|
|
28
|
+
"@types/react": "^19.1.8",
|
|
29
|
+
"@types/react-dom": "^19.1.6",
|
|
30
|
+
"@vitejs/plugin-react": "^4.6.0",
|
|
31
|
+
"tailwindcss": "^4.1.11",
|
|
32
|
+
"typescript": "^5.8.3",
|
|
33
|
+
"vite-tsconfig-paths": "^5.1.4"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Link } from '@tanstack/react-router';
|
|
2
|
+
import { HomeLayout } from 'fumadocs-ui/layouts/home';
|
|
3
|
+
|
|
4
|
+
export function NotFound() {
|
|
5
|
+
return (
|
|
6
|
+
<HomeLayout
|
|
7
|
+
nav={{
|
|
8
|
+
title: 'Tanstack Start',
|
|
9
|
+
}}
|
|
10
|
+
className="text-center py-32 justify-center"
|
|
11
|
+
>
|
|
12
|
+
<div className="flex flex-col items-center gap-4">
|
|
13
|
+
<h1 className="text-6xl font-bold text-fd-muted-foreground">404</h1>
|
|
14
|
+
<h2 className="text-2xl font-semibold">Page Not Found</h2>
|
|
15
|
+
<p className="text-fd-muted-foreground max-w-md">
|
|
16
|
+
The page you are looking for might have been removed, had its name
|
|
17
|
+
changed, or is temporarily unavailable.
|
|
18
|
+
</p>
|
|
19
|
+
<Link
|
|
20
|
+
to="/"
|
|
21
|
+
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"
|
|
22
|
+
>
|
|
23
|
+
Back to Home
|
|
24
|
+
</Link>
|
|
25
|
+
</div>
|
|
26
|
+
</HomeLayout>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -7,31 +7,19 @@ import {
|
|
|
7
7
|
} from 'fumadocs-core/source';
|
|
8
8
|
import matter from 'gray-matter';
|
|
9
9
|
import * as path from 'node:path';
|
|
10
|
-
import
|
|
11
|
-
import * as fs from 'node:fs';
|
|
10
|
+
import * as icons from 'lucide-static';
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
import: 'default',
|
|
21
|
-
}),
|
|
22
|
-
);
|
|
23
|
-
} else {
|
|
24
|
-
files = globSync('content/docs/**/*').map((file) => {
|
|
25
|
-
return [file, fs.readFileSync(file).toString()];
|
|
26
|
-
});
|
|
27
|
-
}
|
|
12
|
+
const files = Object.entries(
|
|
13
|
+
import.meta.glob<true, 'raw'>('/content/**/*', {
|
|
14
|
+
eager: true,
|
|
15
|
+
query: '?raw',
|
|
16
|
+
import: 'default',
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
28
19
|
|
|
29
20
|
const virtualFiles: VirtualFile[] = files.flatMap(([file, content]) => {
|
|
30
21
|
const ext = path.extname(file);
|
|
31
|
-
const virtualPath = path.relative(
|
|
32
|
-
'content/docs',
|
|
33
|
-
path.join(process.cwd(), file),
|
|
34
|
-
);
|
|
22
|
+
const virtualPath = path.relative('content', path.join(process.cwd(), file));
|
|
35
23
|
|
|
36
24
|
if (ext === '.mdx' || ext === '.md') {
|
|
37
25
|
const parsed = matter(content);
|
|
@@ -67,4 +55,12 @@ export const source = loader({
|
|
|
67
55
|
metaData: MetaData;
|
|
68
56
|
}>,
|
|
69
57
|
baseUrl: '/docs',
|
|
58
|
+
// @ts-expect-error -- string
|
|
59
|
+
icon(icon) {
|
|
60
|
+
if (!icon) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (icon in icons) return icons[icon as keyof typeof icons];
|
|
65
|
+
},
|
|
70
66
|
});
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { createRouter as createTanStackRouter } from '@tanstack/react-router';
|
|
2
2
|
import { routeTree } from './routeTree.gen';
|
|
3
|
+
import { NotFound } from './components/NotFound';
|
|
3
4
|
|
|
4
5
|
export function createRouter() {
|
|
5
6
|
return createTanStackRouter({
|
|
6
7
|
routeTree,
|
|
8
|
+
defaultPreload: 'intent',
|
|
7
9
|
scrollRestoration: true,
|
|
10
|
+
defaultNotFoundComponent: NotFound,
|
|
8
11
|
});
|
|
9
12
|
}
|
|
10
13
|
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
2
|
import {
|
|
3
3
|
createRootRoute,
|
|
4
4
|
HeadContent,
|
|
5
5
|
Outlet,
|
|
6
6
|
Scripts,
|
|
7
7
|
} from '@tanstack/react-router';
|
|
8
|
+
import * as React from 'react';
|
|
9
|
+
import appCss from '~/styles/app.css?url';
|
|
8
10
|
import { RootProvider } from 'fumadocs-ui/provider/base';
|
|
9
|
-
import appCss from '../app.css?url';
|
|
10
11
|
import { TanstackProvider } from 'fumadocs-core/framework/tanstack';
|
|
11
12
|
|
|
12
13
|
export const Route = createRootRoute({
|
|
@@ -36,7 +37,7 @@ function RootComponent() {
|
|
|
36
37
|
);
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
function RootDocument({ children }:
|
|
40
|
+
function RootDocument({ children }: { children: React.ReactNode }) {
|
|
40
41
|
return (
|
|
41
42
|
<html suppressHydrationWarning>
|
|
42
43
|
<head>
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createServerFileRoute } from '@tanstack/react-start/server';
|
|
2
2
|
import { createSearchAPI } from 'fumadocs-core/search/server';
|
|
3
|
-
import { source } from '
|
|
3
|
+
import { source } from '~/lib/source';
|
|
4
4
|
import { structure } from 'fumadocs-core/mdx-plugins';
|
|
5
5
|
|
|
6
6
|
const server = createSearchAPI('advanced', {
|
|
7
7
|
indexes: source.getPages().map((page) => ({
|
|
8
8
|
id: page.url,
|
|
9
9
|
url: page.url,
|
|
10
|
-
title: page.data.title
|
|
11
|
-
description: page.data.description,
|
|
10
|
+
title: page.data.title!,
|
|
12
11
|
structuredData: structure(page.data.content),
|
|
13
12
|
})),
|
|
14
13
|
});
|
|
15
14
|
|
|
16
|
-
export const
|
|
17
|
-
GET: ({ request }) =>
|
|
18
|
-
return server.GET(request);
|
|
19
|
-
},
|
|
15
|
+
export const ServerRoute = createServerFileRoute('/api/search').methods({
|
|
16
|
+
GET: async ({ request }) => server.GET(request),
|
|
20
17
|
});
|
|
@@ -1,32 +1,31 @@
|
|
|
1
1
|
import { createFileRoute, notFound } from '@tanstack/react-router';
|
|
2
|
+
import { executeMdxSync } from '@fumadocs/mdx-remote/client';
|
|
2
3
|
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
|
3
|
-
import { source } from '@/lib/source';
|
|
4
4
|
import {
|
|
5
5
|
DocsBody,
|
|
6
6
|
DocsDescription,
|
|
7
7
|
DocsPage,
|
|
8
8
|
DocsTitle,
|
|
9
9
|
} from 'fumadocs-ui/page';
|
|
10
|
-
import { executeMdxSync } from '@fumadocs/mdx-remote/client';
|
|
11
|
-
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
|
12
10
|
import { createServerFn } from '@tanstack/react-start';
|
|
13
|
-
import type { PageTree } from 'fumadocs-core/server';
|
|
14
11
|
import { createCompiler } from '@fumadocs/mdx-remote';
|
|
15
|
-
import
|
|
12
|
+
import { source } from '~/lib/source';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
import defaultMdxComponents from 'fumadocs-ui/mdx';
|
|
15
|
+
import type { PageTree } from 'fumadocs-core/server';
|
|
16
|
+
import { useMemo } from 'react';
|
|
17
|
+
|
|
18
|
+
const compiler = createCompiler();
|
|
16
19
|
|
|
17
20
|
export const Route = createFileRoute('/docs/$')({
|
|
18
21
|
component: Page,
|
|
19
|
-
async
|
|
22
|
+
loader: async ({ params }) => {
|
|
20
23
|
const slugs = (params._splat ?? '').split('/');
|
|
21
|
-
|
|
22
24
|
return loader({ data: slugs });
|
|
23
25
|
},
|
|
24
26
|
});
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
development: false,
|
|
28
|
-
});
|
|
29
|
-
|
|
28
|
+
// a wrapper because we don't want `loader` to be called on client-side
|
|
30
29
|
const loader = createServerFn({
|
|
31
30
|
method: 'GET',
|
|
32
31
|
})
|
|
@@ -37,7 +36,7 @@ const loader = createServerFn({
|
|
|
37
36
|
|
|
38
37
|
const { content, ...rest } = page.data;
|
|
39
38
|
const compiled = await compiler.compileFile({
|
|
40
|
-
path: path.resolve('content
|
|
39
|
+
path: path.resolve('content', page.path),
|
|
41
40
|
value: content,
|
|
42
41
|
});
|
|
43
42
|
|
|
@@ -49,21 +48,51 @@ const loader = createServerFn({
|
|
|
49
48
|
});
|
|
50
49
|
|
|
51
50
|
function Page() {
|
|
52
|
-
const
|
|
53
|
-
const {
|
|
51
|
+
const data = Route.useLoaderData();
|
|
52
|
+
const {
|
|
53
|
+
default: MDX,
|
|
54
|
+
toc,
|
|
55
|
+
tree,
|
|
56
|
+
} = useMemo(() => {
|
|
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]);
|
|
54
79
|
|
|
55
80
|
return (
|
|
56
81
|
<DocsLayout
|
|
82
|
+
tree={tree}
|
|
57
83
|
nav={{
|
|
58
|
-
title: 'Tanstack
|
|
84
|
+
title: 'Fumadocs Tanstack',
|
|
59
85
|
}}
|
|
60
|
-
tree={tree as PageTree.Root}
|
|
61
86
|
>
|
|
62
87
|
<DocsPage toc={toc}>
|
|
63
88
|
<DocsTitle>{data.title}</DocsTitle>
|
|
64
|
-
<DocsDescription>{data.
|
|
89
|
+
<DocsDescription>{data.description}</DocsDescription>
|
|
65
90
|
<DocsBody>
|
|
66
|
-
<
|
|
91
|
+
<MDX
|
|
92
|
+
components={{
|
|
93
|
+
...defaultMdxComponents,
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
67
96
|
</DocsBody>
|
|
68
97
|
</DocsPage>
|
|
69
98
|
</DocsLayout>
|
|
@@ -11,11 +11,14 @@ function Home() {
|
|
|
11
11
|
nav={{
|
|
12
12
|
title: 'Tanstack Start',
|
|
13
13
|
}}
|
|
14
|
-
className="text-center py-32"
|
|
14
|
+
className="text-center py-32 justify-center"
|
|
15
15
|
>
|
|
16
16
|
<h1 className="font-medium text-xl mb-4">Fumadocs on Tanstack Start.</h1>
|
|
17
17
|
<Link
|
|
18
18
|
to="/docs/$"
|
|
19
|
+
params={{
|
|
20
|
+
_splat: '',
|
|
21
|
+
}}
|
|
19
22
|
className="px-3 py-2 rounded-lg bg-fd-primary text-fd-primary-foreground font-medium text-sm mx-auto"
|
|
20
23
|
>
|
|
21
24
|
Open Docs
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
+
"include": ["**/*.ts", "**/*.tsx"],
|
|
2
3
|
"compilerOptions": {
|
|
4
|
+
"strict": true,
|
|
5
|
+
"esModuleInterop": true,
|
|
3
6
|
"jsx": "react-jsx",
|
|
4
|
-
"moduleResolution": "Bundler",
|
|
5
|
-
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
|
6
|
-
"types": ["node", "vite/client"],
|
|
7
7
|
"module": "ESNext",
|
|
8
|
-
"
|
|
8
|
+
"moduleResolution": "Bundler",
|
|
9
|
+
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
|
10
|
+
"isolatedModules": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
9
12
|
"skipLibCheck": true,
|
|
10
|
-
"
|
|
13
|
+
"target": "ES2022",
|
|
14
|
+
"allowJs": true,
|
|
15
|
+
"forceConsistentCasingInFileNames": true,
|
|
16
|
+
"baseUrl": ".",
|
|
11
17
|
"paths": {
|
|
12
|
-
"
|
|
13
|
-
}
|
|
18
|
+
"~/*": ["./src/*"]
|
|
19
|
+
},
|
|
20
|
+
"noEmit": true
|
|
14
21
|
}
|
|
15
22
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
|
|
2
|
+
import { defineConfig } from 'vite';
|
|
3
|
+
import tsConfigPaths from 'vite-tsconfig-paths';
|
|
4
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
5
|
+
import react from '@vitejs/plugin-react';
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
server: {
|
|
9
|
+
port: 3000,
|
|
10
|
+
},
|
|
11
|
+
plugins: [
|
|
12
|
+
tailwindcss(),
|
|
13
|
+
tsConfigPaths({
|
|
14
|
+
projects: ['./tsconfig.json'],
|
|
15
|
+
}),
|
|
16
|
+
tanstackStart({
|
|
17
|
+
customViteReactPlugin: true,
|
|
18
|
+
}),
|
|
19
|
+
react(),
|
|
20
|
+
],
|
|
21
|
+
});
|