Skip to content

Commit 61f2662

Browse files
authored
feat: better separation of mdx content and headings support (nodejs#5467)
1 parent 05152df commit 61f2662

File tree

9 files changed

+626
-663
lines changed

9 files changed

+626
-663
lines changed

next.config.mjs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const nextConfig = {
77
// We intentionally disable Next.js's built-in i18n support
88
// as we dom have our own i18n and internationalisation engine
99
i18n: null,
10+
// We want to always enforce that SWC minifies the sources even during Development mode
11+
// so that bundles are minified on-the-go. SWF minifying is fast, and has almost no penalties
1012
swcMinify: true,
1113
// We don't use trailing slashes on URLs from the Node.js Website
1214
trailingSlash: false,
@@ -30,18 +32,10 @@ const nextConfig = {
3032
// We disable the support for legacy browsers which should reduce the polyiffing
3133
// and the overall bundle size for the Node.js Website client runtime
3234
legacyBrowsers: false,
33-
// This feature reduces the Next.js memory consumption by compartimentalising
34-
// the Webpack builds into smaller threads that are responsible for building
35-
// smaller pieces of the website instead of all pages at onces
36-
// this increases slightly build time in favor of less memory usage
37-
webpackBuildWorker: true,
3835
// Some of our static pages from `getStaticProps` have a lot of data
3936
// since we pass the fully-compiled MDX page from `MDXRemote` through
4037
// a page's static props.
4138
largePageDataBytes: 128 * 100000,
42-
// This allows us to use SuperJson which supports custom data types for the JSON schema
43-
// @see https://github.com/blitz-js/superjson
44-
swcPlugins: [['next-superjson-plugin', {}]],
4539
// We disable the bundling and tracing of some files on the Serverless & Edge Runtimes
4640
// as otherwise they would explode the bundle size (server) and the tracing time
4741
outputFileTracingExcludes: {

next.dynamic.mjs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import { join } from 'node:path';
44
import { readFileSync } from 'node:fs';
5+
import { VFile } from 'vfile';
56
import remarkGfm from 'remark-gfm';
7+
import remarkHeadings from '@vcarl/remark-headings';
68
import { serialize } from 'next-mdx-remote/serialize';
79
import * as nextLocales from './next.locales.mjs';
810
import * as nextConstants from './next.constants.mjs';
@@ -139,20 +141,34 @@ export const getStaticProps = async (source = '', filename = '') => {
139141
// We only attempt to serialize data if the `source` has content and `filename` has content
140142
// otherwise we return a 404 since this means that it is not a valid file or a file we should care about
141143
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+
142148
// This act as a MDX "compiler" but, lightweight. It parses the Markdown
143149
// string source into a React Component tree, and then it serializes it
144150
// it also supports Remark plugins, and MDX components
145151
// Note.: We use the filename extension to define the mode of execution
146-
const content = await serialize(source, {
152+
const { compiledSource } = await serialize(sourceAsVirtualFile, {
147153
parseFrontmatter: true,
148154
mdxOptions: {
149-
remarkPlugins: [remarkGfm],
155+
remarkPlugins: [remarkGfm, remarkHeadings],
150156
format: filename.includes('.mdx') ? 'mdx' : 'md',
151157
},
152158
});
153159

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+
154168
// 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 };
156172
staticProps.notFound = false;
157173
}
158174

0 commit comments

Comments
 (0)