The loadServerPageIndex utility reads a markdown file and extracts page metadata for use in sitemaps. It parses the markdown content, extracts titles, descriptions, sections, and keywords, and derives additional metadata like URL prefix from the file path.
Note
This function is primarily used internally by
loadServerSitemapto process individual page files. Most users won't need to call it directly.
import { loadServerPageIndex } from '@mui/internal-docs-infra/pipeline/loadServerPageIndex';
// Load metadata from a markdown file
const pageData = await loadServerPageIndex('file:///path/to/docs-infra/components/page.mdx');
// Returns: { title: 'Docs Infra Components', prefix: '/docs-infra/components/', pages: [...] }
The function:
markdownToMetadata to extract page dataSitemapSectionData objectimport { loadServerPageIndex } from '@mui/internal-docs-infra/pipeline/loadServerPageIndex';
const data = await loadServerPageIndex('file:///app/docs-infra/functions/page.mdx');
// Returns:
// {
// title: 'Docs Infra Functions',
// prefix: '/docs-infra/functions/',
// pages: [
// {
// slug: 'load-server-code-meta',
// path: './load-server-code-meta/page.mdx',
// title: 'Load Server Code Meta',
// description: 'Parses demo files to extract variant information...',
// keywords: ['code', 'meta', 'demo'],
// sections: { ... }
// },
// // ... more pages
// ]
// }
When your files are not at the default location:
import { createLoadServerPageIndex } from '@mui/internal-docs-infra/pipeline/loadServerPageIndex';
const loadPageIndex = createLoadServerPageIndex({
rootContext: '/custom/docs/root',
});
const data = await loadPageIndex('file:///custom/docs/root/components/page.mdx');
// prefix will be '/components/' instead of the full path
The loader automatically processes file paths to generate useful metadata.
Converts kebab-case path segments to Title Case:
import { pathSegmentToTitle } from '@mui/internal-docs-infra/pipeline/loadServerPageIndex';
pathSegmentToTitle('docs-infra'); // 'Docs Infra'
pathSegmentToTitle('code-highlighter'); // 'Code Highlighter'
pathSegmentToTitle('abstract-create-demo'); // 'Abstract Create Demo'
The extractPrefixAndTitle function generates URL prefixes from directory structure:
import { extractPrefixAndTitle } from '@mui/internal-docs-infra/pipeline/loadServerPageIndex';
extractPrefixAndTitle('/app/docs-infra/components/page.mdx', '/app');
// { prefix: '/docs-infra/components/', title: 'Docs Infra Components' }
extractPrefixAndTitle('/app/(public)/blog/page.mdx', '/app');
// { prefix: '/blog/', title: 'Blog' } (route groups are removed)
extractPrefixAndTitle('/src/app/page.mdx', '/src/app');
// { prefix: '/', title: '' }
Note
extractPrefixAndTitleexpects absolute file paths (withoutfile://prefix), not file URLs.
The following are automatically removed from paths:
src - Only if at the startapp - Only if at the start (or after src)(public), (content). and empty stringsfunction loadServerPageIndex(filePath: string): Promise<SitemapSectionData | null>;
Loads page metadata from a markdown file using the default root context (process.cwd()).
Parameters:
| Parameter | Type | Description |
|---|---|---|
filePath | string | File URL (file://) or absolute path to the markdown file |
Returns: Promise resolving to SitemapSectionData or null if parsing fails.
Throws: Error if the file cannot be read.
function createLoadServerPageIndex(options?: CreateLoadServerPageIndexOptions): LoadServerPageIndex;
Creates a custom loadServerPageIndex function with specific options.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
options.rootContext | string | process.cwd() | Root directory for resolving relative paths |
Returns: A LoadServerPageIndex function.
function pathSegmentToTitle(segment: string): string;
Converts a kebab-case path segment to Title Case.
Parameters:
| Parameter | Type | Description |
|---|---|---|
segment | string | Path segment to convert |
Returns: Title-cased string.
function extractPrefixAndTitle(
absolutePath: string,
rootContext: string,
): { prefix: string; title: string };
Extracts URL prefix and section title from a file path.
Parameters:
| Parameter | Type | Description |
|---|---|---|
absolutePath | string | Absolute path to the markdown file |
rootContext | string | Root directory for relative paths |
Returns: Object with prefix (URL path) and title (human-readable).
function stripTitleMarkdown(hierarchy: HeadingHierarchy): Record<string, SitemapSection>;
Recursively removes titleMarkdown AST fields from a heading hierarchy to reduce bundle size.
Parameters:
| Parameter | Type | Description |
|---|---|---|
hierarchy | HeadingHierarchy | Heading hierarchy with AST nodes |
Returns: Cleaned hierarchy without markdown AST nodes.
interface SitemapSectionData {
title: string;
prefix: string;
pages: SitemapPage[];
}
interface SitemapPage {
slug: string;
path: string;
title: string;
description?: string;
keywords?: string[];
sections?: Record<string, SitemapSection>;
}
interface SitemapSection {
title: string;
children?: Record<string, SitemapSection>;
}
interface CreateLoadServerPageIndexOptions {
/**
* The root context directory for resolving relative paths.
* Defaults to process.cwd().
*/
rootContext?: string;
}
The loader automatically optimizes the metadata to reduce bundle size:
descriptionMarkdown - Raw markdown AST for descriptions (can be 50%+ of size)titleMarkdown - Raw markdown AST for section titleschildren: {} - Empty children objects are converted to undefinedBefore optimization:
{
sections: {
features: {
title: 'Features',
titleMarkdown: { type: 'root', children: [...] }, // Removed
children: {} // Converted to undefined
}
},
descriptionMarkdown: { type: 'root', children: [...] } // Removed
}
After optimization:
{
sections: {
features: {
title: 'Features',
children: undefined
}
}
}
loadServerSitemap - Uses this to load all pages in a sitemaptransformMarkdownMetadata - Remark plugin that extracts metadataloadPrecomputedSitemap - Build-time sitemap processing