Reusable snippets
Create reusable content snippets with variables to maintain consistency across documentation pages and reduce duplication in your MDX files.
One of the core principles of software development is DRY (Don’t Repeat Yourself), which applies to documentation too. If you find yourself repeating the same content in multiple places, create a custom snippet for that content. Snippets contain content that you can import into other files to reuse. You control where the snippet appears on a page. If you ever need to update the content, you only need to edit the snippet rather than every file where the snippet appears.
Snippets are not currently supported in the web editor. To use snippets, edit your MDX files locally with the CLI or push snippet imports directly to your repository.
How snippets work
Snippets are any .mdx, .md, .js, or .jsx files imported into another file. You can place snippet files anywhere in your project.
When you import a snippet into another file, the snippet only appears where you import it and does not render as a standalone page. Any file in the /snippets/ folder is always a snippet even if it is not imported into another file.
Create snippets
Create a file with the content you want to reuse. Snippets can contain all content types supported by Mintlify and they can import other snippets. See Nested snippets for where to declare imports when nesting.
Import snippets into pages
Import snippets into pages using either an absolute or relative path.
- Absolute imports: Start with
/for imports from the root of your project. - Relative imports: Use
./or../to import snippets relative to the current file’s location.
The name you use to render an imported snippet as a JSX tag must start with an uppercase letter, such as MySnippet. MDX treats lowercase tags such as <mySnippet /> as literal HTML or custom element names rather than references to imported snippets.
Relative imports enable IDE navigation. Press Cmd and click a snippet name in your editor to jump directly to the snippet definition.
Import text
Add content to your snippet file
Add the content you want to reuse.
Hello world! This is my content I want to reuse across pages.Import the snippet into your destination file
Use either an absolute or relative path.
---
title: "An example page"
description: "This is an example page that imports a snippet."
---
import MySnippet from "/shared/my-snippet.mdx";
The snippet content displays beneath this sentence.
<MySnippet />Nested snippets
Snippets can import other snippets. Declare the import in the snippet file that uses the nested snippet, not in the page that imports the parent snippet.
Each file resolves its own imports. Imports declared on a page do not apply to the snippets that the page imports. A nested snippet that relies on a page-level import may render as empty content.
Import the nested snippet in the parent snippet file
Declare the import where you want to use the nested snippet.
import ChildSnippet from "/shared/child-snippet.mdx";
This snippet renders another snippet beneath this sentence.
<ChildSnippet />Import only the parent snippet in your destination file
You do not need to import the nested snippet.
---
title: "An example page"
description: "This is an example page that imports a snippet containing a nested snippet."
---
import ParentSnippet from "/shared/parent-snippet.mdx";
<ParentSnippet />Import variables
Reference variables from a snippet in a page.
Export variables from a snippet file
export const myName = "Ronan";
export const myObject = { fruit: "strawberries" };
;Import the snippet from your destination file and use the variable
---
title: "An example page"
description: "This is an example page that imports a snippet with variables."
---
import { myName, myObject } from "/shared/custom-variables.mdx";
Hello, my name is {myName} and I like {myObject.fruit}.Browsers evaluate MDX expressions, such as imported variables like {myName} and inline expressions like {1 + 1}. Their values do not appear in a page’s initial HTML or in offline exports, so crawlers, LLMs, and other tools that do not run JavaScript see the surrounding text without them. Write values as plain text if they must be visible in those situations.
Import snippets with variables
Use variables to pass data to a snippet when you import it.
Add variables to your snippet
Pass in properties when you import it. In this example, the variable is {word}.
My keyword of the day is {word}.Import the snippet into your destination file with the variable
The passed property replaces the variable in the snippet definition.
---
title: "An example page"
description: "This is an example page that imports a snippet with a variable."
---
import MySnippet from "/shared/my-snippet.mdx";
<MySnippet word="bananas" />Variables also interpolate inside fenced code blocks. This is useful for snippets that include installation commands or other code examples that differ by package name, version, or environment.
export const InstallSnippet = ({ packageName }) => <></>;
Install the package:
```bash
npm install {packageName}
```import InstallSnippet from "/shared/install-snippet.mdx";
<InstallSnippet packageName="@myorg/sdk" />Import React components
Create a snippet with a JSX component
See React components for more information.
export const MyJSXSnippet = () => {
return (
<div>
<h1>Hello, world!</h1>
</div>
);
};When creating JSX snippets, use arrow function syntax (=>) rather than function declarations. The function keyword is not supported in snippets.
Import the snippet
---
title: "An example page"
description: "This is an example page that imports a snippet with a React component."
---
import { MyJSXSnippet } from "/components/my-jsx-snippet.jsx";
<MyJSXSnippet />Render content from structured data
Keep data such as a list of SDK components, a support matrix, or a set of plans in one snippet and render it on multiple pages. When you modify the data, every table, list, or card built from it updates.
Store the data as a plain JSON object in a .js snippet with a named export. Then write a .jsx snippet that turns the data into markup.
Snippets must be .mdx, .md, .js, or .jsx files. You cannot import a .json or .yaml file directly. Keep the data in a .js snippet, or generate one from your JSON or YAML source.
Export the data from a snippet
export const sdkComponents = [
{ "name": "CardForm", "version": "2.4.0", "status": "Stable", "docs": "/components/card-form" },
{ "name": "PinReveal", "version": "1.9.2", "status": "Beta", "docs": "/components/pin-reveal" }
];Create a snippet that renders the data
Loop over the data with map() and return HTML elements or Mintlify components.
export const ComponentsTable = ({ rows }) => (
<table>
<thead>
<tr>
<th>Component</th>
<th>Version</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{rows.map((row) => (
<tr key={row.name}>
<td><a href={row.docs}>{row.name}</a></td>
<td><code>{row.version}</code></td>
<td>{row.status}</td>
</tr>
))}
</tbody>
</table>
);Import both snippets and pass the data as a property
Filter or sort the data in the page to show a subset without duplicating it.
---
title: "SDK components"
description: "Every component in the SDK, with its current version and status."
---
import { sdkComponents } from "/snippets/sdk-components.js";
import { ComponentsTable } from "/snippets/components-table.jsx";
The SDK includes {sdkComponents.length} components.
<ComponentsTable rows={sdkComponents} />
## Stable components
<ComponentsTable rows={sdkComponents.filter((row) => row.status === "Stable")} />Generate snippets and pages from JSON or YAML
If you store data in a JSON or YAML file, generate snippets from that source data. Use a script to write the data snippet with one page per entry and create the matching navigation group. Run the script in CI whenever the source file changes and commit the result.
Write the generator
This script reads sdk-components.yaml, writes the snippet from the previous example, creates a page for each component, and replaces the pages of the navigation group named “Components” in docs.json.
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { parse } from "yaml";
const components = parse(readFileSync("sdk-components.yaml", "utf8"));
const slug = (name) => name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
// One snippet with all the data, for tables and lists anywhere in the docs.
writeFileSync("snippets/sdk-components.js", `export const sdkComponents = ${JSON.stringify(components, null, 2)};\n`);
// One page per component.
mkdirSync("components", { recursive: true });
for (const component of components) {
const page = `---
title: ${JSON.stringify(component.name)}
description: ${JSON.stringify(component.description)}
---
{/* Generated from sdk-components.yaml by scripts/generate-docs.mjs. Edit the YAML, not this file. */}
| Field | Value |
| --- | --- |
| Version | \`${component.version}\` |
| Status | ${component.status} |
`;
writeFileSync(`components/${slug(component.name)}.mdx`, page);
}
// Keep the navigation in sync: replace the pages of the group named "Components", wherever it sits.
const docs = JSON.parse(readFileSync("docs.json", "utf8"));
const findGroup = (node) => (Array.isArray(node) ? node.map(findGroup).find(Boolean) : node && typeof node === "object" ? (node.group === "Components" ? node : findGroup(Object.values(node))) : undefined);
const group = findGroup(docs.navigation);
if (group) {
group.pages = components.map((component) => `components/${slug(component.name)}`);
writeFileSync("docs.json", `${JSON.stringify(docs, null, 2)}\n`);
}For a JSON source, replace parse() with JSON.parse() and skip the yaml dependency. Running the script twice produces identical files, so it is safe to run on every push.
Run it in a GitHub Action
The workflow runs when the source file or the script changes, then commits whatever the script produced. The default GITHUB_TOKEN does not trigger other workflows when it pushes, so the job cannot loop. Mintlify deploys the push like any other commit.
name: Generate docs from YAML
on:
push:
paths:
- sdk-components.yaml
- scripts/generate-docs.mjs
workflow_dispatch:
permissions:
contents: write
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm install yaml
- run: node scripts/generate-docs.mjs
- name: Commit generated files
run: |
git add -A
if git diff --cached --quiet; then
echo "Nothing changed."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git commit -m "docs: regenerate from sdk-components.yaml"
git pushIf you store the source file in another repository, run the workflow there instead. Check out the docs repository with a token that can push to it, run the script, and commit.