Vite
React Router
Use Fumadocs MDX with React Router
Setup
npm i fumadocs-mdx fumadocs-core @types/mdx
Create the configuration file:
import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
export const docs = defineDocs({
dir: 'content/docs',
});
export default defineConfig();
Add the Vite plugin:
import { reactRouter } from '@react-router/dev/vite';
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
import mdx from 'fumadocs-mdx/vite';
import * as MdxConfig from './source.config';
export default defineConfig({
plugins: [mdx(MdxConfig), tailwindcss(), reactRouter(), tsconfigPaths()],
});
Integrate with Fumadocs
To integrate with Fumadocs, make a lib/source.ts
file:
import { loader } from 'fumadocs-core/source';
import { create, docs } from '../../source.generated';
export const source = loader({
source: await create.sourceAsync(docs.doc, docs.meta),
baseUrl: '/docs',
});
The source.generated.ts
file will be generated when you run development server or production build.
Done
The configuration is now finished.
Examples
Rendering Content
As React Router doesn't support RSC at the moment, use toClientRenderer()
to lazy load MDX content as a component on browser.
For example:
import type { Route } from './+types/page';
import { source } from '@/lib/source';
import { docs } from '../../source.generated';
import { toClientRenderer } from 'fumadocs-mdx/runtime/vite';
export async function loader({ params }: Route.LoaderArgs) {
const slugs = params['*'].split('/').filter((v) => v.length > 0);
const page = source.getPage(slugs);
if (!page) throw new Response('Not found', { status: 404 });
return {
path: page.path,
};
}
const renderer = toClientRenderer(docs.doc, ({ default: Mdx, frontmatter }) => {
return (
<div className="prose">
<h1>{frontmatter.title}</h1>
<Mdx />
</div>
);
});
export default function Page(props: Route.ComponentProps) {
const { path } = props.loaderData;
const Content = renderer[path];
return <Content />;
}
Note that you can import the source.generated.ts
file directly, it's useful to access compiled content without loader()
.
import { docs } from './source.generated';
console.log(docs);
How is this guide?
Last updated on