Skip to Content
Fumadocs

Validate Links

Ensure your links are correct.

Setup

You can use next-validate-link to validate your links in content files.

This guide is mainly for Fumadocs MDX, see the docs of next-validate-link for other setups.

Create a script that scans the routes of your app. populate lists the params of your docs route:

scripts/lint.ts
import { type FileObject, printErrors, scanURLs, validateFiles } from 'next-validate-link';
import { source } from '@/lib/source';

const scanned = await scanURLs({
  preset: 'next',
  populate: {
    'docs/[[...slug]]': source.getPages().map((page) => ({
      value: { slug: page.slugs },
      hashes: getHeadings(page),
    })),
  },
});

In the same script, validate your content files against the scanned URLs:

scripts/lint.ts
printErrors(
  await validateFiles(await getFiles(), {
    scanned,
    // check `href` attributes in different MDX components
    markdown: {
      components: {
        Card: { attributes: ['href'] },
      },
    },
    // check relative paths
    checkRelativePaths: 'as-url',
  }),
  true,
);

function getHeadings({ data }: (typeof source)['$inferPage']): string[] {
  return data.toc.map((item) => item.url.slice(1));
}

function getFiles() {
  const promises = source.getPages().map(async (page): Promise<FileObject> => ({
    path: page.absolutePath,
    content: await page.data.getText('raw'),
    url: page.url,
    data: page.data,
  }));

  return Promise.all(promises);
}

Running Lint

To access the source object outside of app runtime, configure Fumadocs MDX Loader for Bun.

Then, run the script to validate links:

bun ./scripts/lint.ts

Node.js Loader

You might need to configure TypeScript transpiling (or newer version of Node.js), and Fumadocs MDX Loader.

Without special reasons, using Bun or tsx would be simpler.

How is this guide?

Last updated on