GraphQL
Generating docs for GraphQL schema.
Setup
Install the required packages.
npm i @fumadocs/graphql graphqlGenerate Styles
Add the following line:
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
@import '@fumadocs/graphql/css/preset.css';Configure Plugin
Create the GraphQL server instance and the <GraphQLPage /> component.
import { createGraphQL } from '@fumadocs/graphql/server';
// note: this is a server-side API
export const graphql = createGraphQL({
// the GraphQL schema, it accepts:
// SDL files/URLs (including `extend type`), SDL text,
// introspection results, and `GraphQLSchema` instances.
input: ['./schema.graphql'],
});See createGraphQL() and createGraphQLPage() for their options.
Generate Pages
Pass staticSource() to your loader(). It generates pages without writing files.
staticSource() reads files, so source.ts becomes server-only. Move docs into collections.ts for client code to import.
import { loader } from 'fumadocs-core/source';
import { defineDocs } from 'fumadocs-mdx/macro';
import { docs } from '@/lib/collections';
import { graphql } from '@/lib/graphql';
export const docs = defineDocs({
dir: 'content/docs',
docs: {
async: true,
},
});
// server-only now, as `staticSource()` reads files
export const source = loader(
{
docs: docs.toFumadocsSource(),
graphql: await graphql.staticSource({
baseDir: 'graphql',
}),
},
{
baseUrl: '/docs',
// optional: adds a query/mutation/subscription badge to each page item in page tree
plugins: [graphql.loaderPlugin()],
},
);staticSource() generates a page per operation, grouped into folders by kind (e.g. queries/). Pages of named types are opt-in.
Pages of source now have two types, docs and graphql. Update every place that uses source.
Render GraphQL pages with <GraphQLPage /> in your docs page:
import { docs, source } from '@/lib/source';
import { docs } from '@/lib/collections';
import { source } from '@/lib/source';
import { GraphQLPage } from '@/components/api-page';
import type { OperationExample } from '@fumadocs/graphql';
// the type-level check of server function results can't verify the examples of operations,
// register them as serializable (install `@tanstack/router-core` if it isn't resolvable)
declare module '@tanstack/router-core' {
interface SerializableExtensions {
graphqlExample: OperationExample;
}
}
export const Route = createFileRoute('/docs/$')({
component: Page,
loader: async ({ params }) => {
const slugs = params._splat?.split('/') ?? [];
const data = await serverLoader({ data: slugs });
if (data.type === 'docs') await docs.getPage(data.path)?.preload();
return data;
},
});
const serverLoader = createServerFn({
method: 'GET',
})
.validator((slugs: string[]) => slugs)
.handler(async ({ data: slugs }) => {
const page = source.getPage(slugs);
if (!page) throw notFound();
const pageTree = await source.serializePageTree(source.getPageTree());
if (page.type === 'graphql') {
return {
type: 'graphql',
title: page.data.title,
props: page.data.getGraphQLPageProps(),
pageTree,
};
}
return { type: 'docs', path: page.path, pageTree };
});
function Page() {
const data = useFumadocsLoader(Route.useLoaderData());
return (
<DocsLayout {...baseOptions()} tree={data.pageTree}>
{data.type === 'graphql' && (
<DocsPage full>
<DocsTitle>{data.title}</DocsTitle>
<DocsBody>
<GraphQLPage {...data.props} />
</DocsBody>
</DocsPage>
)}
<Suspense>
{data.type === 'docs' && <Content path={data.path} />}
</Suspense>
</DocsLayout>
);
}Ensure the migration is complete!
Run a type check before continuing:
npm run types:checkFeatures
The official GraphQL integration supports:
- A page per operation (query/mutation/subscription), with the types it uses explored in place
- Arguments, fields, deprecations, default values and
@oneOfinput objects - Directives applied in the schema, with their definitions
- Example requests and responses, generated or from your own operations
- Code samples in cURL, JavaScript, Go, Python, Java, C# and Rust
- A playground with a variables form, it runs subscriptions over WebSocket or SSE too
- Markdown of pages for LLMs
- Optional pages for named types, with their usages across the schema
Demo
See the GraphQL example.
How is this guide?
Last updated on
