|
2 | 2 |
|
3 | 3 | import { join } from 'node:path';
|
4 | 4 | import { readFileSync } from 'node:fs';
|
| 5 | +import { VFile } from 'vfile'; |
5 | 6 | import remarkGfm from 'remark-gfm';
|
| 7 | +import remarkHeadings from '@vcarl/remark-headings'; |
6 | 8 | import { serialize } from 'next-mdx-remote/serialize';
|
7 | 9 | import * as nextLocales from './next.locales.mjs';
|
8 | 10 | import * as nextConstants from './next.constants.mjs';
|
@@ -139,20 +141,34 @@ export const getStaticProps = async (source = '', filename = '') => {
|
139 | 141 | // We only attempt to serialize data if the `source` has content and `filename` has content
|
140 | 142 | // otherwise we return a 404 since this means that it is not a valid file or a file we should care about
|
141 | 143 | if (source.length && filename.length) {
|
| 144 | + // We create a VFile (Virtual File) to be able to access some contextual |
| 145 | + // data post serialization (compilation) of the source Markdown into MDX |
| 146 | + const sourceAsVirtualFile = new VFile(source); |
| 147 | + |
142 | 148 | // This act as a MDX "compiler" but, lightweight. It parses the Markdown
|
143 | 149 | // string source into a React Component tree, and then it serializes it
|
144 | 150 | // it also supports Remark plugins, and MDX components
|
145 | 151 | // Note.: We use the filename extension to define the mode of execution
|
146 |
| - const content = await serialize(source, { |
| 152 | + const { compiledSource } = await serialize(sourceAsVirtualFile, { |
147 | 153 | parseFrontmatter: true,
|
148 | 154 | mdxOptions: {
|
149 |
| - remarkPlugins: [remarkGfm], |
| 155 | + remarkPlugins: [remarkGfm, remarkHeadings], |
150 | 156 | format: filename.includes('.mdx') ? 'mdx' : 'md',
|
151 | 157 | },
|
152 | 158 | });
|
153 | 159 |
|
| 160 | + // After the MDX gets processed with the remarkPlugins, some extra `data` that might come along |
| 161 | + // the `frontmatter` comes from `serialize` built-in support to `remark-frontmatter` |
| 162 | + const { headings, matter: rawFrontmatter } = sourceAsVirtualFile.data; |
| 163 | + |
| 164 | + // This serialises the Frontmatter into a JSON object that is compatible with the |
| 165 | + // `getStaticProps` supported data type for props. (No prop value can be an object or not a primitive) |
| 166 | + const frontmatter = JSON.parse(JSON.stringify(rawFrontmatter)); |
| 167 | + |
154 | 168 | // this defines the basic props that should be passed back to the `DynamicPage` component
|
155 |
| - staticProps.props = { content }; |
| 169 | + // We only want the `compiledSource` as we use `MDXProvider` for custom components along the journey |
| 170 | + // And then we want the frontmatter and heading information from the VFile `data` |
| 171 | + staticProps.props = { content: compiledSource, headings, frontmatter }; |
156 | 172 | staticProps.notFound = false;
|
157 | 173 | }
|
158 | 174 |
|
|
0 commit comments