Skip to main content
Mintlify

Search documentation

Type to search this documentation.

On this pageOverview

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 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 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 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.

  1. Add content to your snippet file

    Add the content you want to reuse.

    shared/my-snippet.mdx
    Hello world! This is my content I want to reuse across pages.
  2. Import the snippet into your destination file

    Use either an absolute or relative path.

    Absolute
    ---
    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 />
    Relative
    ---
    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 />

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.

  1. Import the nested snippet in the parent snippet file

    Declare the import where you want to use the nested snippet.

    shared/parent-snippet.mdx
    import ChildSnippet from "/shared/child-snippet.mdx";
    
    This snippet renders another snippet beneath this sentence.
    
    <ChildSnippet />
  2. Import only the parent snippet in your destination file

    You do not need to import the nested snippet.

    destination-file.mdx
    ---
    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 />

Reference variables from a snippet in a page.

  1. Export variables from a snippet file

    shared/custom-variables.mdx
    export const myName = "Ronan";
    
    export const myObject = { fruit: "strawberries" };
    
    ;
  2. Import the snippet from your destination file and use the variable

    destination-file.mdx
    ---
    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}.

Use variables to pass data to a snippet when you import it.

  1. Add variables to your snippet

    Pass in properties when you import it. In this example, the variable is {word}.

    shared/my-snippet.mdx
    My keyword of the day is {word}.
  2. Import the snippet into your destination file with the variable

    The passed property replaces the variable in the snippet definition.

    destination-file.mdx
    ---
    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.

shared/install-snippet.mdx
export const InstallSnippet = ({ packageName }) => <></>;

Install the package:

```bash
npm install {packageName}
```
destination-file.mdx
import InstallSnippet from "/shared/install-snippet.mdx";

<InstallSnippet packageName="@myorg/sdk" />
  1. Create a snippet with a JSX component

    See React components for more information.

    components/my-jsx-snippet.jsx
    export const MyJSXSnippet = () => {
      return (
        <div>
          <h1>Hello, world!</h1>
        </div>
      );
    };
  2. Import the snippet

    destination-file.mdx
    ---
    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 />

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.

  1. Export the data from a snippet

    snippets/sdk-components.js
    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" }
    ];
  2. Create a snippet that renders the data

    Loop over the data with map() and return HTML elements or Mintlify components.

    snippets/components-table.jsx
    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>
    );
  3. 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.

    destination-file.mdx
    ---
    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

Section titled “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.

  1. 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.

    scripts/generate-docs.mjs
    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.

  2. 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.

    .github/workflows/generate-docs.yml
    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 push

    If 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.

Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu