You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+102-19
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@
4
4
5
5
# next-mdx-remote
6
6
7
-
A set of light utilities allowing mdx to be loaded within `getStaticProps` or `getServerSideProps` and hydrated correctly on the client.
7
+
A set of light utilities allowing MDX to be loaded within `getStaticProps` or `getServerSideProps` and hydrated correctly on the client.
8
8
9
9
-->
10
10
@@ -15,11 +15,15 @@ A set of light utilities allowing mdx to be loaded within `getStaticProps` or `g
15
15
## Installation
16
16
17
17
```sh
18
-
# using npm
19
-
npm i next-mdx-remote
18
+
npm install next-mdx-remote
19
+
```
20
+
21
+
If using with Turbopack, you'll need to add the following to your `next.config.js` until [this issue](https://github.com/vercel/next.js/issues/64525) is resolved:
20
22
21
-
# using yarn
22
-
yarn add next-mdx-remote
23
+
```diff
24
+
const nextConfig = {
25
+
+ transpilePackages: ['next-mdx-remote'],
26
+
}
23
27
```
24
28
25
29
## Examples
@@ -50,7 +54,7 @@ export async function getStaticProps() {
50
54
51
55
While it may seem strange to see these two in the same file, this is one of the cool things about Next.js -- `getStaticProps` and `TestPage`, while appearing in the same file, run in two different places. Ultimately your browser bundle will not include `getStaticProps` at all, or any of the functions it uses only on the server, so `serialize` will be removed from the browser bundle entirely.
52
56
53
-
> **IMPORTANT**: Be very careful about putting any `mdx-remote` code into a separate "utilities" file. Doing so will likely cause issues with nextjs' code splitting abilities - it must be able to cleanly determine what is used only on the server side and what should be left in the client bundle. If you put `mdx-remote` code into an external utilities file and something is broken, remove it and start from the simple example above before filing an issue.
57
+
> **IMPORTANT**: Be very careful about putting any `next-mdx-remote` code into a separate "utilities" file. Doing so will likely cause issues with Next.js' code splitting abilities - it must be able to cleanly determine what is used only on the server side and what should be left in the client bundle. If you put `next-mdx-remote` code into an external utilities file and something is broken, remove it and start from the simple example above before filing an issue.
54
58
55
59
### Additional Examples
56
60
@@ -290,15 +294,15 @@ This library exposes a function and a component, `serialize` and `<MDXRemote />`
**`serialize`** consumes a string of MDX. It can also optionally be passed options which are [passed directly to MDX](https://mdxjs.com/docs/extending-mdx/), and a scope object that can be included in the mdx scope. The function returns an object that is intended to be passed into `<MDXRemote />` directly.
297
+
**`serialize`** consumes a string of MDX. It can also optionally be passed options which are [passed directly to MDX](https://mdxjs.com/docs/extending-mdx/), and a scope object that can be included in the MDX scope. The function returns an object that is intended to be passed into `<MDXRemote />` directly.
294
298
295
299
```ts
296
300
serialize(
297
301
// Raw MDX contents as a string
298
302
'# hello, world',
299
303
// Optional parameters
300
304
{
301
-
// made available to the arguments of any custom mdx component
305
+
// made available to the arguments of any custom MDX component
302
306
scope: {},
303
307
// MDX's available options, see the MDX docs for more info.
@@ -307,7 +311,7 @@ This library exposes a function and a component, `serialize` and `<MDXRemote />`
307
311
rehypePlugins: [],
308
312
format: 'mdx',
309
313
},
310
-
// Indicates whether or not to parse the frontmatter from the mdx source
314
+
// Indicates whether or not to parse the frontmatter from the MDX source
311
315
parseFrontmatter: false,
312
316
}
313
317
)
@@ -342,9 +346,9 @@ Note: `th/td` won't work because of the "/" in the component name.
342
346
343
347
## Background & Theory
344
348
345
-
There isn't really a good default way to load mdx files in a Next.js app. Previously, we wrote [`next-mdx-enhanced`](https://github.com/hashicorp/next-mdx-enhanced) in order to be able to render your MDX files into layouts and import their front matter to create index pages.
349
+
There isn't really a good default way to load MDX files in a Next.js app. Previously, we wrote [`next-mdx-enhanced`](https://github.com/hashicorp/next-mdx-enhanced) in order to be able to render your MDX files into layouts and import their front matter to create index pages.
346
350
347
-
This workflow from mdx-enhanced was fine, but introduced a few limitations that we have removed with `next-mdx-remote`:
351
+
This workflow from `next-mdx-enhanced` was fine, but introduced a few limitations that we have removed with `next-mdx-remote`:
348
352
349
353
-**The file content must be local.** You cannot store MDX files in another repo, a database, etc. For a large enough operation, there will end up being a split between those authoring content and those working on presentation of the content. Overlapping these two concerns in the same repo makes a more difficult workflow for everyone.
350
354
-**You are bound to filesystem-based routing.** Your pages are generated with urls according to their locations. Or maybe you remap them using `exportPathMap`, which creates confusion for authors. Regardless, moving pages around in any way breaks things -- either the page's url or your `exportPathMap` configuration.
@@ -353,13 +357,13 @@ This workflow from mdx-enhanced was fine, but introduced a few limitations that
353
357
354
358
So, `next-mdx-remote` changes the entire pattern so that you load your MDX content not through an import, but rather through `getStaticProps` or `getServerProps` -- you know, the same way you would load any other data. The library provides the tools to serialize and hydrate the MDX content in a manner that is performant. This removes all of the limitations listed above, and does so at a significantly lower cost -- `next-mdx-enhanced` is a very heavy library with a lot of custom logic and [some annoying limitations](https://github.com/hashicorp/next-mdx-enhanced/issues/17). Our informal testing has shown build times reduced by 50% or more.
355
359
356
-
Since this project was initially created, Kent C Dodds has made a similar project, [`mdx-bundler`](https://github.com/kentcdodds/mdx-bundler). This library supports imports and exports within a mdx file (as long as you manually read each imported file and pass its contents) and automatically processes frontmatter. If you have a lot of files that all import and use different components, you may benefit from using `mdx-bundler`, as `next-mdx-remote` currently only allows components to be imported and made available across all pages. It's important to note that this functionality comes with a cost though - `mdx-bundler`'s output is at least 400% larger than the output from `next-mdx-remote` for basic markdown content.
360
+
Since this project was initially created, Kent C. Dodds has made a similar project, [`mdx-bundler`](https://github.com/kentcdodds/mdx-bundler). This library supports imports and exports within a MDX file (as long as you manually read each imported file and pass its contents) and automatically processes frontmatter. If you have a lot of files that all import and use different components, you may benefit from using `mdx-bundler`, as `next-mdx-remote` currently only allows components to be imported and made available across all pages. It's important to note that this functionality comes with a cost though - `mdx-bundler`'s output is at least 400% larger than the output from `next-mdx-remote` for basic markdown content.
357
361
358
362
### How Can I Build A Blog With This?
359
363
360
-
Data has shown that 99% of use cases for all developer tooling are building unnecessarily complex personal blogs. Just kidding. But seriously, if you are trying to build a blog for personal or small business use, consider just using normal html and css. You definitely do not need to be using a heavy full-stack javascript framework to make a simple blog. You'll thank yourself later when you return to make an update in a couple years and there haven't been 10 breaking releases to all of your dependencies.
364
+
Data has shown that 99% of use cases for all developer tooling are building unnecessarily complex personal blogs. Just kidding. But seriously, if you are trying to build a blog for personal or small business use, consider just using normal HTML and CSS. You definitely do not need to be using a heavy full-stack JavaScript framework to make a simple blog. You'll thank yourself later when you return to make an update in a couple years and there haven't been 10 breaking releases to all of your dependencies.
361
365
362
-
If you really insist though, check out [our official nextjs example implementation](https://github.com/vercel/next.js/tree/canary/examples/with-mdx-remote). 💖
366
+
If you really insist though, check out [our official Next.js example implementation](https://github.com/vercel/next.js/tree/canary/examples/with-mdx-remote). 💖
363
367
364
368
## Caveats
365
369
@@ -388,9 +392,9 @@ This project does include native types for TypeScript use. Both `serialize` and
388
392
Below is an example of a simple implementation in TypeScript. You may not need to implement the types exactly in this way for every configuration of TypeScript - this example is just a demonstration of where the types could be applied if needed.
## React Server Components (RSC) & Next.js `app` Directory Support
419
423
420
-
> **Warning**
421
-
> We consider the `next-mdx-remote/rsc` API to be unstable. Use at your own discretion, and be aware that the API and behavior might change between minor and/or patch releases.
422
-
423
424
Usage of `next-mdx-remote` within server components, and specifically within Next.js's `app` directory, is supported by importing from `next-mdx-remote/rsc`. Previously, the serialization and render steps were separate, but going forward RSC makes this separation unnecessary.
424
425
425
426
Some noteworthy differences:
@@ -543,6 +544,88 @@ This is from Server Components!
543
544
}
544
545
```
545
546
547
+
## Alternatives
548
+
549
+
`next-mdx-remote` is opinionated in what features it supports. If you need additional features not provided by `next-mdx-remote`, here are a few alternatives to consider:
If you're using React Server Components and just trying to use basic MDX with custom components, you don't need anything other than the core MDX library.
558
+
559
+
```js
560
+
import { compile, run } from'@mdx-js/mdx'
561
+
import*asruntimefrom'react/jsx-runtime'
562
+
importClientComponentfrom'./components/client'
563
+
564
+
// MDX can be retrieved from anywhere, such as a file or a database.
You can also simplify this approach with `evaluate`, which compiles and runs code in a single call if you don't plan on passing the compiled string to a database or client component.
590
+
591
+
```js
592
+
import { evaluate } from'@mdx-js/mdx'
593
+
import*asruntimefrom'react/jsx-runtime'
594
+
importClientComponentfrom'./components/client'
595
+
596
+
// MDX can be retrieved from anywhere, such as a file or a database.
0 commit comments