Skip to content

Commit 1390ce0

Browse files
authored
Sync (#2708)
* MDX: reduce cwd usage * MDX: prototype workspace feature * Bump deps * Core: Respect `title` in images * fix serialization * MDX: implement core for workspaces * MDX: introduce official workspace API * fix Tanstack Start * MDX: fix `lastModified` plugin on workspace * MDX: add unit tests for workspace * Core: Expose Zod schema for page & meta data * Core & UI: support `collapsible` in meta data * MDX: fix index file re-generation * Merge pull request #2705 from fuma-nama/changeset-release/dev Version Packages * Docs: introduce `collapsible` & MDX workspace
2 parents 2621cd9 + 4216811 commit 1390ce0

File tree

77 files changed

+2480
-1901
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+2480
-1901
lines changed

apps/docs/app/api/[transport]/route.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,7 @@ const handler = createMcpHandler(
7575
);
7676
},
7777
{},
78-
{
79-
basePath: '/api',
80-
},
78+
{ basePath: '/api', disableSse: true },
8179
);
8280

83-
export { handler as GET, handler as POST };
81+
export { handler as GET, handler as POST, handler as DELETE };

apps/docs/content/docs/headless/page-conventions.mdx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,13 @@ Customise folders by creating a `meta.json` file in the folder.
118118
}
119119
```
120120

121-
| name | description |
122-
| ------------- | ------------------------------------- |
123-
| `title` | Display name |
124-
| `icon` | The name of icon, see [Icons](#icons) |
125-
| `pages` | Folder items (see below) |
126-
| `defaultOpen` | Open the folder by default |
121+
| name | description |
122+
| ------------- | -------------------------------------------- |
123+
| `title` | Display name |
124+
| `icon` | The name of icon, see [Icons](#icons) |
125+
| `defaultOpen` | Open the folder by default |
126+
| `collapsible` | Collapsible folder content (default: `true`) |
127+
| `pages` | Folder items (see below) |
127128

128129
### Pages
129130

apps/docs/content/docs/mdx/collections.mdx

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,76 @@ export const blog = defineCollections({
125125

126126
> This API is only available on `doc` type.
127127
128-
See [Postprocess](/docs/mdx/postprocess).
128+
You can pass build-time information to runtime using the `postprocess` API.
129+
130+
- #### `includeProcessedMarkdown`
131+
132+
Include the processed Markdown content (before being converted into HTML).
133+
134+
```ts tab="docs"
135+
import { defineDocs } from 'fumadocs-mdx/config';
136+
137+
export default defineDocs({
138+
docs: {
139+
postprocess: {
140+
// [!code ++]
141+
includeProcessedMarkdown: true,
142+
},
143+
},
144+
});
145+
```
146+
147+
```ts tab="doc"
148+
import { defineCollections } from 'fumadocs-mdx/config';
149+
150+
export const blog = defineCollections({
151+
type: 'doc',
152+
postprocess: {
153+
// [!code ++]
154+
includeProcessedMarkdown: true,
155+
},
156+
});
157+
```
158+
159+
You can obtain the included content with `getText()` (e.g. in Fumadocs):
160+
161+
```ts
162+
import { source } from '@/lib/source';
163+
164+
const page = source.getPage('...');
165+
console.log(await page.data.getText('processed'));
166+
```
167+
168+
- #### `valueToExport`
169+
170+
Some remark plugins store their output in `vfile.data` (compile-time memory) which cannot be accessed from your code.
171+
172+
You can specify the name of properties to include, they will get converted into ESM exports that you can access when importing the MDX file.
173+
174+
```ts tab="docs"
175+
import { defineDocs } from 'fumadocs-mdx/config';
176+
177+
export default defineDocs({
178+
docs: {
179+
postprocess: {
180+
// [!code ++]
181+
valueToExport: ['dataName'],
182+
},
183+
},
184+
});
185+
```
186+
187+
```ts tab="doc"
188+
import { defineCollections } from 'fumadocs-mdx/config';
189+
190+
export const blog = defineCollections({
191+
type: 'doc',
192+
postprocess: {
193+
// [!code ++]
194+
valueToExport: ['dataName'],
195+
},
196+
});
197+
```
129198

130199
## Define Docs
131200

apps/docs/content/docs/mdx/postprocess.mdx

Lines changed: 0 additions & 78 deletions
This file was deleted.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
title: Workspace
3+
description: Use Fumadocs MDX in multiple workspace.
4+
---
5+
6+
## Overview
7+
8+
**Workspace** in Fumadocs MDX, refers to an independent project with its own config and content.
9+
10+
<Files>
11+
<Folder name="my-workspace" defaultOpen>
12+
<Folder name="content/docs" defaultOpen>
13+
<File name="index.mdx" />
14+
<File name="test.mdx" />
15+
</Folder>
16+
<File name="source.config.ts" />
17+
</Folder>
18+
<Folder name="content/docs" defaultOpen>
19+
<File name="welcome.mdx" />
20+
</Folder>
21+
<File name="source.config.ts" />
22+
</Files>
23+
24+
<Callout title="Good to Know">
25+
Fumadocs MDX Workspace is not limited to the traditional meaning of workspace
26+
in package managers.
27+
28+
They do not need to have its own `package.json`, only a config file is needed.
29+
30+
</Callout>
31+
32+
To define a workspace, add:
33+
34+
```ts title="source.config.ts"
35+
import { defineConfig } from 'fumadocs-mdx/config';
36+
37+
export default defineConfig({
38+
workspaces: {
39+
'my-workspace': {
40+
dir: 'my-workspace',
41+
config: await import('./my-workspace/source.config.ts'),
42+
},
43+
},
44+
});
45+
```
46+
47+
When writing content in a workspace, note that:
48+
49+
- `cwd` refers to the **current workspace directory**.
50+
- configs will not inherit, workspaces are always independent.
51+
52+
By running dev or build server, you should see collection entries from all workspaces to be generated.
53+
54+
### Accessing Collections
55+
56+
You can access the generated files of a workspace at `.source/{workspace}/*`. For example:
57+
58+
```ts title="lib/source.ts"
59+
import { docs } from 'fumadocs-mdx:collections/my-workspace/server';
60+
```
61+
62+
> The output location of root workspace is not changed.
63+
64+
To integrate multiple sources in Fumadocs, use [`multiple`](/docs/headless/source-api/source#multiple-sources):
65+
66+
```ts title="lib/source.ts"
67+
import { loader, multiple } from 'fumadocs-core/source';
68+
import { docs } from 'fumadocs-mdx:collections/server';
69+
import * as MyWorkspace from 'fumadocs-mdx:collections/my-workspace/server';
70+
71+
export const source = loader(
72+
multiple({
73+
root: docs.toFumadocsSource(),
74+
'my-workspace': MyWorkspace.docs.toFumadocsSource(),
75+
}),
76+
{
77+
baseUrl: '/docs',
78+
},
79+
);
80+
```
81+
82+
## When to Use
83+
84+
In some setups, you might have multiple Fumadocs MDX configs with their own content directory.
85+
86+
With workspaces, you can integrate them into one Fumadocs MDX config, and access all collections of each workspace.
87+
88+
This is cruial for use cases like storing content across multiple repos, a simpified setup would be:
89+
90+
- let your main docs repo be $A$, and other repos be $T_n$
91+
- for each repo $T_n$:
92+
- $T_n$ has $A$ as a git submodule.
93+
- $T_n$ defines its own config `source.config.ts` and work independently.
94+
- when a commit is made to the content in $T_n$, it triggers a GitHub action (or CI), which creates a new deployment on $A$.
95+
- when a deployment is triggered on $A$:
96+
- Fumadocs MDX handles each $T_n$ as a workspace.
97+
- each workspace generates its own collection entries, e.g. `fumadocs-mdx:collections/{repo}/server`.
98+
- Fumadocs `loader()` integrate multiple sources into one.

apps/docs/package.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
"@radix-ui/react-hover-card": "^1.1.15",
2525
"@radix-ui/react-presence": "^1.1.5",
2626
"@radix-ui/react-tooltip": "^1.2.8",
27-
"@shikijs/rehype": "^3.18.0",
28-
"@shikijs/transformers": "^3.18.0",
29-
"@takumi-rs/image-response": "^0.55.4",
27+
"@shikijs/rehype": "^3.19.0",
28+
"@shikijs/transformers": "^3.19.0",
29+
"@takumi-rs/image-response": "^0.56.0",
3030
"ai": "^5.0.106",
3131
"class-variance-authority": "^0.7.1",
3232
"d3-force": "^3.0.0",
@@ -43,13 +43,13 @@
4343
"hast-util-to-jsx-runtime": "^2.3.6",
4444
"katex": "^0.16.25",
4545
"lucide-react": "^0.555.0",
46-
"mermaid": "^11.12.1",
47-
"next": "16.0.6",
46+
"mermaid": "^11.12.2",
47+
"next": "16.0.7",
4848
"next-themes": "^0.4.6",
4949
"octokit": "^5.0.5",
5050
"oxc-transform": "^0.101.0",
51-
"react": "^19.2.0",
52-
"react-dom": "^19.2.0",
51+
"react": "^19.2.1",
52+
"react-dom": "^19.2.1",
5353
"react-force-graph-2d": "^1.29.0",
5454
"react-remove-scroll": "^2.7.2",
5555
"rehype-katex": "^7.0.1",
@@ -59,17 +59,17 @@
5959
"remark-mdx": "^3.1.1",
6060
"remark-rehype": "^11.1.2",
6161
"scroll-into-view-if-needed": "^3.1.0",
62-
"shiki": "^3.18.0",
62+
"shiki": "^3.19.0",
6363
"tailwind-merge": "^3.4.0",
6464
"twoslash": "^0.3.4",
6565
"unist-util-visit": "^5.0.0",
6666
"zod": "^4.1.13"
6767
},
6868
"devDependencies": {
6969
"@fumadocs/cli": "workspace:*",
70-
"@next/bundle-analyzer": "16.0.6",
71-
"@next/env": "16.0.6",
72-
"@next/eslint-plugin-next": "16.0.6",
70+
"@next/bundle-analyzer": "16.0.7",
71+
"@next/env": "16.0.7",
72+
"@next/eslint-plugin-next": "16.0.7",
7373
"@tailwindcss/postcss": "^4.1.17",
7474
"@types/d3-force": "^3.0.10",
7575
"@types/estree": "^1.0.8",

examples/astro/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
"@astrojs/mdx": "^4.3.12",
1515
"@astrojs/react": "^4.4.2",
1616
"@orama/orama": "^3.1.16",
17-
"astro": "^5.16.3",
17+
"astro": "^5.16.4",
1818
"fumadocs-core": "workspace:*",
1919
"fumadocs-ui": "workspace:*",
20-
"react": "^19.2.0",
21-
"react-dom": "^19.2.0",
20+
"react": "^19.2.1",
21+
"react-dom": "^19.2.1",
2222
"sharp": "^0.34.5"
2323
},
2424
"devDependencies": {

examples/content-collections/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
"@fumadocs/content-collections": "workspace:*",
1212
"fumadocs-core": "workspace:*",
1313
"fumadocs-ui": "workspace:*",
14-
"next": "16.0.6",
15-
"react": "^19.2.0",
16-
"react-dom": "^19.2.0"
14+
"next": "16.0.7",
15+
"react": "^19.2.1",
16+
"react-dom": "^19.2.1"
1717
},
1818
"devDependencies": {
1919
"@content-collections/core": "^0.12.0",

examples/fp/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
"fumadocs-mdx": "workspace:*",
1414
"fumadocs-ui": "workspace:*",
1515
"fumapress": "workspace:*",
16-
"react": "^19.2.0",
17-
"react-dom": "^19.2.0",
18-
"react-router": "^7.9.6"
16+
"react": "^19.2.1",
17+
"react-dom": "^19.2.1",
18+
"react-router": "^7.10.0"
1919
},
2020
"devDependencies": {
2121
"@remix-run/node-fetch-server": "^0.12.0",

examples/i18n/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
"fumadocs-core": "workspace:*",
1414
"fumadocs-mdx": "workspace:*",
1515
"fumadocs-ui": "workspace:*",
16-
"next": "16.0.6",
17-
"react": "^19.2.0",
18-
"react-dom": "^19.2.0"
16+
"next": "16.0.7",
17+
"react": "^19.2.1",
18+
"react-dom": "^19.2.1"
1919
},
2020
"devDependencies": {
2121
"@types/mdx": "^2.0.13",

0 commit comments

Comments
 (0)