Add MDX support to Next.js 13 and format them with tailwind typography
Introduction
MDX is a superset of markdown that lets you write JSX directly in your markdown files. It is a powerful way to add dynamic interactivity and embed React components within your content.
Next.js can support both local MDX content inside your application, as well as remote MDX files fetched dynamically on the server. The Next.js plugin handles tranforming Markdown and React components into HTML, including support for usage in Server Components (default in app).
Create next.js app
Run the following command to create the next.js app.
npx create-next-app@latest nextjs-mdx-tailwind --typescript --eslint
✔ Would you like to use `src/` directory with this project? … No / Yes
✔ Would you like to use experimental `app/` directory with this project? … No / Yes
✔ What import alias would you like configured? … @/*
Creating a new Next.js app in /home/siavash/code/blog/articles/nextjs13-mdx-tailwind-typography/nextjs-mdx-tailwind.
Using npm.
Initializing project with template: app
Installing dependencies:
- react
- react-dom
- next
- typescript
- @types/react
- @types/node
- @types/react-dom
- eslint
- eslint-config-next
added 272 packages, and audited 273 packages in 14s
103 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Success! Created nextjs-mdx-tailwind at /home/siavash/code/blog/articles/nextjs13-mdx-tailwind-typography/nextjs-mdx-tailwind
Install tailwind and tailwind typography
Install tailwind and tailwind typography using npm.
cd nextjs-mdx-tailwind
npm install -D tailwindcss postcss autoprefixer @tailwindcss/typography
Configure tailwind.config.js for next.js
Initialize tailwind and open the configuration file.
npx tailwindcss init -p
code tailwind.config.js
Add the following content.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx}',
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
// Or if using `src` directory:
'./src/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {},
},
plugins: [require('@tailwindcss/typography')],
}
Add the Tailwind directives to your CSS
code globals.css
Add the following content.
@tailwind base;
@tailwind components;
@tailwind utilities;
Install and configure MDX
In this section the next.js documentation is followed to setup MDX for next.js.
Install the @next/mdx and remark-gfm packages.
npm install @next/mdx remark-gfm
Create mdx-components.jsx in the root of your application (not inside app)
// This file allows you to provide custom React components
// to be used in MDX files. You can import and use any
// React component you want, including components from
// other libraries.
function H1({ children }) {
return <h1>{children}</h1>
}
function H2({ children }) {
return <h2>{children}</h2>
}
function H3({ children }) {
return <h3>{children}</h3>
}
function H4({ children }) {
return <h4>{children}</h4>
}
function H5({ children }) {
return <h5>{children}</h5>
}
export function useMDXComponents(components) {
return { h1: H1, h2: H2, h3: H3, h4: H4, h5: H5, ...components }
}
Update next.config.mjs to use @next/mdx and Github flavor markdown.
import createMDX from '@next/mdx'
import remarkGfm from 'remark-gfm'
/** @type {import('next').NextConfig} */
const nextConfig = {
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
experimental: {
appDir: true,
mdxRs: false, // Disable this to work with remarkGfm
},
}
const withMDX = createMDX({
extension: /\.mdx?$/,
options: {
remarkPlugins: [remarkGfm],
rehypePlugins: [],
},
})
export default withMDX(nextConfig)
Install @types/mdx to add a type for mdx files for typescript to recognize it.
npm install -D @types/mdx
Add a app/hello.mdx file with MDX content to your app directory.
## Heading
# H1
## H2
### H3
#### H4
##### H5
###### H6
## Emphasis
_italics text_ and **bold text**.
## Lists
1. Ordered list item
2. Another item
- Unordered list item
- Second item
## Links
[google](https://www.google.com)
## Images

## Code and Syntax Highlighting
Inline `code` has `back-ticks around` it.
```javascript
var s = 'Code block'
alert(s)
```
## Tables
| Col1 | Cl2 | Col3 |
| ---- | ----- | ---- |
| 1 | One | 12 |
| 2 | Two | 12 |
| 3 | Three | 1 |
## Blockquotes
> Blockquotes are done like this.
> Several line part of the same quote.
> You can put **Markdown** here also.
Import the MDX file inside a app/page.tsx to display the content.
import HelloWorld from './hello.mdx'
export default function Page() {
return (
<div className="container prose mx-auto mt-36">
<HelloWorld />
</div>
)
}
Note: The prose class adds the styling to the mdx output.
Source code
The source code can be found here