Integration with Frameworks
This guide provides examples for integrating GraphQL-Markdown with popular documentation frameworks.
General Integration Approachβ
Most documentation frameworks allow you to generate documentation during the build process. You can integrate GraphQL-Markdown by creating a script that runs before your documentation build.
Basic Integration Exampleβ
import { runGraphQLMarkdown } from '@graphql-markdown/cli';
const config = {
schema: './schema.graphql',
rootPath: './docs',
};
await runGraphQLMarkdown(config);
Custom MDX Formatterβ
When integrating with frameworks other than Docusaurus, you'll need to create a custom MDX module to format documentation elements (badges, admonitions, etc.) using your framework's components.
MDX Module Structureβ
A custom MDX module can export individual formatter functions:
| Export | Type | Description |
|---|---|---|
formatMDXBadge | (badge: { text, classname? }) => string | Format type badges (deprecated, required, etc.) |
formatMDXAdmonition | (admonition: { text, title, type, icon? }, meta?) => string | Format callout/warning blocks |
formatMDXBullet | (text?: string) => string | Format bullet point separators |
formatMDXDetails | (option: { dataOpen, dataClose? }) => string | Format collapsible sections |
formatMDXFrontmatter | (props?, formatted?: string[]) => string | Format page frontmatter |
formatMDXLink | (link: { text, url }) => { text, url } | Transform type links |
formatMDXNameEntity | (name: string, parentType?: string) => string | Format named entity references |
formatMDXSpecifiedByLink | (url: string) => string | Format scalar specification links |
formatMDXDetails contractThe string returned by formatMDXDetails must contain a single \r (carriage return) character as a delimiter between the opening part and the closing part. The printer splits on "\r" to wrap generated content inside the collapsible element, so reserve \r only for that separator and use \n for all regular line breaks inside the returned string.
Do not use CRLF (\r\n) for normal line endings in formatMDXDetails, because any extra \r characters will also be treated as delimiters.
// β
correct β use \n for normal line breaks and a single standalone \r as the delimiter
export const formatMDXDetails = ({ dataOpen }) =>
`\n\n<MyDetails label="${dataOpen}">\n\r</MyDetails>\n\n`;
// β incorrect β no \r means the closing tag is lost and items render outside
export const formatMDXDetails = ({ dataOpen }) =>
`\n\n<MyDetails label="${dataOpen}">\n</MyDetails>\n\n`;
// β incorrect β CRLF introduces extra \r characters that break result.split("\r")
export const formatMDXDetails = ({ dataOpen }) =>
`\r\n\r\n<MyDetails label="${dataOpen}">\r\n\r</MyDetails>\r\n\r\n`;
Additionally, the module can export:
| Export | Type | Description |
|---|---|---|
mdxDeclaration | string | Import statements prepended to generated files |
mdxExtension | string | Custom file extension (defaults to .mdx) |
You only need to export the formatter functions your framework requires. Any missing functions will use the default HTML-like implementation.
Lifecycle Hooksβ
The custom MDX module can also export lifecycle hooks to customize the generation process. See Hooks Recipes for the full hook reference and usage examples.
Framework-Specific Integrationβ
Docusaurusβ
The official Docusaurus integration is available as a dedicated package:
With the default @graphql-markdown/docusaurus/mdx parser, collapsible sections are emitted as native <details>/<summary> markup.
Custom summary labels are rendered with open/closed spans and toggled with CSS (data-collapsed and [open] selectors), so no custom <Details> React component is required.
const path = require('node:path');
module.exports = {
// ... other docusaurus config
plugins: [
[
'@graphql-markdown/docusaurus',
{
schema: path.join(__dirname, 'schema.graphql'),
rootPath: path.join(__dirname, 'docs'),
baseURL: 'api',
},
],
],
};
For more details, check the @graphql-markdown/docusaurus package.
Astro Starlightβ
For Astro Starlight integration, create a custom MDX module:
// src/modules/astro-mdx.cjs
/**
* Import statement prepended to every generated MDX file.
*/
const mdxDeclaration = `import { Aside, Badge } from '@astrojs/starlight/components';`;
/**
* Optional: Custom file extension for generated files.
*/
const mdxExtension = ".mdx";
/**
* Format badge elements (e.g., "deprecated", "required")
*/
const formatMDXBadge = ({ text, classname }) => {
const variant = classname === "DEPRECATED" ? 'caution' : 'default';
return `<Badge variant="${variant}" text="${text}"/>`;
};
/**
* Format admonition/callout blocks (warnings, notes, tips)
*/
const formatMDXAdmonition = ({ text, title, type }, meta) => {
const asideType = type === "warning" ? "caution" : "note";
return `<Aside type="${asideType}" title="${title}">${text}</Aside>`;
};
module.exports = {
mdxDeclaration,
mdxExtension,
formatMDXBadge,
formatMDXAdmonition,
};
See complete implementation: demo-astro-starlight
Next.js with Fumadocsβ
For Next.js using Fumadocs, create a custom MDX module:
// lib/fumadocs-mdx.cjs
const mdxDeclaration = `
import { Callout } from 'fumadocs-ui/components/callout';
import Chip from '@mui/material/Chip';
`;
/**
* Format badge elements
*/
const formatMDXBadge = ({ text, classname }) => {
const color = classname === "DEPRECATED" ? 'warning' : 'info';
return `<Chip color="${color}" label="${text}" size="small" variant="outlined"/>`;
};
/**
* Format admonition/callout blocks
*/
const formatMDXAdmonition = ({ text, title, type }, meta) => {
const calloutType = type === "warning" ? "warn" : "info";
return `<Callout type="${calloutType}" title="${title}">${text}</Callout>`;
};
module.exports = {
mdxDeclaration,
formatMDXBadge,
formatMDXAdmonition,
};
See complete implementation: demo-nextjs-fumadocs
Vocsβ
For Vocs integration, create a custom MDX module:
// lib/vocs-mdx.cjs
const mdxDeclaration = `
import Chip from '@mui/material/Chip';
export const Bullet = () => <><span style={{ fontWeight: 'normal', fontSize: '.5em' }}> β </span></>
`;
/**
* Format badge elements
*/
const formatMDXBadge = ({ text, classname }) => {
const color = classname === "DEPRECATED" ? 'warning' : 'info';
return `<Chip color="${color}" label="${text}" size="small" variant="outlined"/>`;
};
/**
* Format admonition/callout blocks
*/
const formatMDXAdmonition = ({ text, title, type }, meta) => {
const calloutType = type === "warning" ? "warning" : "info";
return `:::${calloutType}[${title}]${text}:::`;
};
/**
* Format bullet point separators using custom Bullet component
*/
const formatMDXBullet = (text = "") => {
return `<Bullet/>${text}`;
};
module.exports = {
mdxDeclaration,
formatMDXBadge,
formatMDXAdmonition,
formatMDXBullet,
};
See complete implementation: demo-vite-vocs
VitePressβ
For VitePress support, check the package graphql-markdown-vitepress.