Skip to content

Commit

Permalink
feat: better separation of mdx content and headings support (#5467)
Browse files Browse the repository at this point in the history
  • Loading branch information
ovflowd committed Jul 4, 2023
1 parent 05152df commit 61f2662
Show file tree
Hide file tree
Showing 9 changed files with 626 additions and 663 deletions.
10 changes: 2 additions & 8 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const nextConfig = {
// We intentionally disable Next.js's built-in i18n support
// as we dom have our own i18n and internationalisation engine
i18n: null,
// We want to always enforce that SWC minifies the sources even during Development mode
// so that bundles are minified on-the-go. SWF minifying is fast, and has almost no penalties
swcMinify: true,
// We don't use trailing slashes on URLs from the Node.js Website
trailingSlash: false,
Expand All @@ -30,18 +32,10 @@ const nextConfig = {
// We disable the support for legacy browsers which should reduce the polyiffing
// and the overall bundle size for the Node.js Website client runtime
legacyBrowsers: false,
// This feature reduces the Next.js memory consumption by compartimentalising
// the Webpack builds into smaller threads that are responsible for building
// smaller pieces of the website instead of all pages at onces
// this increases slightly build time in favor of less memory usage
webpackBuildWorker: true,
// Some of our static pages from `getStaticProps` have a lot of data
// since we pass the fully-compiled MDX page from `MDXRemote` through
// a page's static props.
largePageDataBytes: 128 * 100000,
// This allows us to use SuperJson which supports custom data types for the JSON schema
// @see https://github.com/blitz-js/superjson
swcPlugins: [['next-superjson-plugin', {}]],
// We disable the bundling and tracing of some files on the Serverless & Edge Runtimes
// as otherwise they would explode the bundle size (server) and the tracing time
outputFileTracingExcludes: {
Expand Down
22 changes: 19 additions & 3 deletions next.dynamic.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import { join } from 'node:path';
import { readFileSync } from 'node:fs';
import { VFile } from 'vfile';
import remarkGfm from 'remark-gfm';
import remarkHeadings from '@vcarl/remark-headings';
import { serialize } from 'next-mdx-remote/serialize';
import * as nextLocales from './next.locales.mjs';
import * as nextConstants from './next.constants.mjs';
Expand Down Expand Up @@ -139,20 +141,34 @@ export const getStaticProps = async (source = '', filename = '') => {
// We only attempt to serialize data if the `source` has content and `filename` has content
// otherwise we return a 404 since this means that it is not a valid file or a file we should care about
if (source.length && filename.length) {
// We create a VFile (Virtual File) to be able to access some contextual
// data post serialization (compilation) of the source Markdown into MDX
const sourceAsVirtualFile = new VFile(source);

// This act as a MDX "compiler" but, lightweight. It parses the Markdown
// string source into a React Component tree, and then it serializes it
// it also supports Remark plugins, and MDX components
// Note.: We use the filename extension to define the mode of execution
const content = await serialize(source, {
const { compiledSource } = await serialize(sourceAsVirtualFile, {
parseFrontmatter: true,
mdxOptions: {
remarkPlugins: [remarkGfm],
remarkPlugins: [remarkGfm, remarkHeadings],
format: filename.includes('.mdx') ? 'mdx' : 'md',
},
});

// After the MDX gets processed with the remarkPlugins, some extra `data` that might come along
// the `frontmatter` comes from `serialize` built-in support to `remark-frontmatter`
const { headings, matter: rawFrontmatter } = sourceAsVirtualFile.data;

// This serialises the Frontmatter into a JSON object that is compatible with the
// `getStaticProps` supported data type for props. (No prop value can be an object or not a primitive)
const frontmatter = JSON.parse(JSON.stringify(rawFrontmatter));

// this defines the basic props that should be passed back to the `DynamicPage` component
staticProps.props = { content };
// We only want the `compiledSource` as we use `MDXProvider` for custom components along the journey
// And then we want the frontmatter and heading information from the VFile `data`
staticProps.props = { content: compiledSource, headings, frontmatter };
staticProps.notFound = false;
}

Expand Down

2 comments on commit 61f2662

@vercel
Copy link

@vercel vercel bot commented on 61f2662 Jul 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 61f2662 Jul 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nodejs-org-stories – ./

nodejs-org-stories-openjs.vercel.app
nodejs-org-storybook.vercel.app
nodejs-org-stories-git-main-openjs.vercel.app

Please sign in to comment.