Reputation: 43
I was trying to use Github Flavored Markdown using @next/mdx
but I can't seem to figure out how to use plugins with the code. Here is what I did:
(I am following along from Next.js Documentation: https://nextjs.org/docs/advanced-features/using-mdx)
1. I created the Next.js App using the command
yarn create next-app next-gfm
2. I then added the required modules to the
yarn add @next/mdx @mdx-js/loader
3. In the pages/
directory, I deleted the index.js
file that was auto generated and replaced it using a index.mdx
file.
From here, I used the following configuration for my next.config.js
file.
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
options: {
remarkPlugins: [],
rehypePlugins: [],
},
})
module.exports = withMDX({
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
})
If we run the code using yarn dev
everything works fine so far.
Here is where the main issue is. I now installed the following packages to use Github Flavored Markdown using the command:
yarn add remark-gfm rehype-stringify
I tried to import the modules in the next.config.js
using the syntax
import remarkGfm from 'remark-gfm'
But this gives me the following error:
import remarkGfm from 'remark-gfm'
^^^^^^
SyntaxError: Cannot use import statement outside a module
module
I have also tried adding the following line at the top of my package.json
"type" : "module",
But this seems to conflict with the require syntax that is being used to import @next/mdx
:
const withMDX = require('@next/mdx')({
...
This gave me the error:
Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error
ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and 'package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
import()
syntaxI did a bit of searching online, and found the import()
syntax. I attempted to do this and my next.config.js
now looked like:
const remarkGfm = import('remark-gfm');
const remarkParse = import('remark-parse')
const remarkRehype = import('remark-rehype')
const rehypeStringify = import('rehype-stringify')
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
options: {
remarkPlugins: [remarkGfm, remarkParse, remarkRehype],
rehypePlugins: [rehypeStringify],
},
})
module.exports = withMDX({
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
})
I tried running this, using the yarn dev
and everything works, except that none of the markdown plugins are functioning at all. (The base markdown is working but if I try using footnotes, or tables it is rendered as plain text).
Could anyone explain how one might proceed using external plugins (e.g Github Flavored Markdown) with MDX and Next.js (using the @next/mdx
package)?
This is my complete project structure and (relevant) files:
next-gfm
|_ pages
|_ index.md
|_ package.json
|_ next.config.js
index.md
# GFM
## Autolink literals
www.example.com, https://example.com, and [email protected].
## Footnote
A note[^1]
[^1]: Big note.
## Strikethrough
~one~ or ~~two~~ tildes.
## Table
| a | b | c | d |
| - | :- | -: | :-: |
## Tasklist
* [ ] to do
* [x] done
package.json
{
"name": "next-mdx-template",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@mdx-js/loader": "^2.1.1",
"@next/mdx": "^12.1.5",
"next": "12.1.5",
"react": "18.0.0",
"react-dom": "18.0.0",
"rehype-katex": "^6.0.2",
"rehype-stringify": "^9.0.3",
"remark-gfm": "^3.0.1",
"remark-math": "^5.1.1",
"remark-mdx": "^2.1.1"
},
"devDependencies": {
"eslint": "8.13.0",
"eslint-config-next": "12.1.5"
}
}
next.config.js
const remarkGfm = import('remark-gfm');
const remarkParse = import('remark-parse')
const remarkRehype = import('remark-rehype')
const rehypeStringify = import('rehype-stringify')
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
options: {
remarkPlugins: [remarkGfm, remarkParse, remarkRehype],
rehypePlugins: [rehypeStringify],
},
})
module.exports = withMDX({
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
})
Upvotes: 4
Views: 7816
Reputation: 4236
next-mdx-remote users:
Run npm i remark-gfm
Create a file mdSerializer.ts
, and inside:
import { serialize } from 'next-mdx-remote/serialize';
import remarkGfm from 'remark-gfm';
const mdSerialize = async (source: string) => {
return await serialize(source, {
mdxOptions: { remarkPlugins: [remarkGfm] },
});
};
export { mdSerialize };
Import mdSerialize
anywhere you'd normally import serialize
For more details around the serialize
API, here
Gfm
example from the original mdx site, here
Upvotes: 2
Reputation: 3715
ES Modules are supported if you rename the config file to next.config.mjs
.
Sources
In your case it might look like,
next.config.mjs
import nextMDX from '@next/mdx'
import remarkGfm from 'remark-gfm'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import rehypeStringify from 'rehype-stringify'
const withMDX = nextMDX({
extension: /\.mdx?$/,
options: {
remarkPlugins: [remarkGfm, remarkParse, remarkRehype],
rehypePlugins: [rehypeStringify],
},
})
export default withMDX({
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
})
Upvotes: 7