DEV Community

Cover image for Getting Started with MDX in Next.js: A Practical Guide
Nitin Sharma
Nitin Sharma

Posted on • Originally published at

Getting Started with MDX in Next.js: A Practical Guide

Web development has come a long way since the early days of writing HTML and JavaScript for creating websites.

Among these technologies and tools, JSX is a particularly noteworthy extension that has gained widespread popularity as the go-to solution for creating immersive and dynamic web content.

However, as web development continues to evolve, so does the need for even more powerful tools. This is where MDX comes in, allowing developers to write JSX directly in markdown files.

In this guide, we will explore the features and benefits of MDX and show you how to use it effectively in a Next.js project.

So, let's dive in!

MDX: What it is and Why You Should Use it?

Before diving deep into MDX, it's important to have a solid understanding of the basics.

As we mentioned in the introduction, MDX enables you to write JSX directly in your markdown files. JSX, which stands for JavaScript XML, can be thought of as a fusion of JavaScript and HTML.

Its syntax looks like this:

const element = <h1>Hello, world!</h1>;
Enter fullscreen mode Exit fullscreen mode

Similarly, Markdown is a lightweight markup language used to format text.

## [Locofy]( converts your designs into production-ready code for different frameworks.
Enter fullscreen mode Exit fullscreen mode

So inside MDX, you can combine markdown with JSX like this:

# Hello, World!
This is a paragraph of regular Markdown text.
<MyComponent prop="value1">
This is a component written in JSX.
Enter fullscreen mode Exit fullscreen mode

But, why should you use MDX?

We know that MDX is a powerful tool that combines the benefits of markdown and React components.

No doubt, Markdown is a popular choice for authoring content because of its simplicity and readability, which allows you to focus on the content rather than the formatting.

While most programmers prefer the markdown approach when writing a blog post, markdown falls short when it comes to creating dynamic content based on user interactivity. This limitation led to the creation of MDX. It is a syntax extension that allows you to use JSX, the syntax used by React, directly in your markdown documents.

With MDX, you can create and use your own React components directly in your markup, making it easy to add interactivity to your content. This opens up a world of possibilities when it comes to composing visually appealing and interactive pages.

It has a wide range of applications, such as for creating content on documentation websites, blogs, e-commerce websites, tutorials and online courses, and even landing pages.

Demystifying MDX: How It Works

Consider the following MDX code:

import { Home } from './Home';

# Welcome to Locofy!

Turn your designs into production-ready frontend code for mobile apps and web

<Home prop="value1" />
Enter fullscreen mode Exit fullscreen mode

This code starts by importing a custom React component called "Home" from a file located in the "Home" directory.

It then includes a Markdown heading, followed by a paragraph of text, and then renders the Home component with a prop.

When this MDX code is compiled, it is transformed into JavaScript code that can be executed by a JavaScript runtime environment like a web browser. The resulting JavaScript code might look something like this:

import { Home } from './Home';
import { Fragment as _Fragment, jsx as _jsx } from 'react/jsx-runtime';

function MDXContent(props) {
  return _jsx(_Fragment, {
    children: [
      _jsx("h1", {
        children: "Welcome to Locofy!"
      }, void 0),
      _jsx("p", {
        children: "Turn your designs into production-ready frontend code for mobile apps and web"
      }, void 0),
      _jsx(Home, {
        prop: "value1"
      }, void 0)

export default MDXContent;
Enter fullscreen mode Exit fullscreen mode

The resulting JSX elements are then rendered as HTML in the web browser. This is how the MDX code works.

Getting Started with MDX in Next.js

To begin, let's create a Next.js app.

- Create a next.js app, by the following command:

npx create-next-app mdx_app
Enter fullscreen mode Exit fullscreen mode

Afterward, run the application to ensure that it is functioning properly.

- Install the required packages:

npm install @next/mdx @mdx-js/loader @mdx-js/react
Enter fullscreen mode Exit fullscreen mode

This command installs three packages: @next/mdx, @mdx-js/loader, and @mdx-js/react.

These packages are commonly used to enable the usage of MDX (Markdown + JSX) syntax for creating dynamic content. @next/mdx is a Next.js specific package for integrating MDX, while @mdx-js/loader and @mdx-js/react are general-purpose packages for loading and rendering MDX content.

- Configuring Next.js for MDX

Now let's configure the Next.js app so that it would know the syntax of MDX in the Next.js app.

For that, go to your "next.config.js" file and paste the below content.

const withMDX = require('@next/mdx')({
  extension: /\.mdx?$/,
  options: {
    // If you use remark-gfm, you'll need to use next.config.mjs
    // as the package is ESM only
    remarkPlugins: [],
    rehypePlugins: [],
    // If you use `MDXProvider`, uncomment the following line.
    // providerImportSource: "@mdx-js/react",

/** @type {import('next').NextConfig} */
const nextConfig = {
  // Configure pageExtensions to include md and mdx
  pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
  // Optionally, add any other Next.js config below
  reactStrictMode: true,

// Merge MDX config with Next.js config
module.exports = withMDX(nextConfig)
Enter fullscreen mode Exit fullscreen mode

Since, we want to run a React component inside an MDX file, create a "components" folder and add a "Hello.js" file inside it. Then, paste the code below into the file.

import React from 'react'
function Hello() {
   return (
       <h1>Hello, World</h1>

export default Hello
Enter fullscreen mode Exit fullscreen mode

- Creating MDX pages in Next.js

Inside your pages directory, create a new file called page.mdx and paste the below content.

import Hello from "../components/Hello.js"

export const name = 'Locofy'
export const title = 'We are from, ' + name + '!'

# {title}

## Here Is Our My MDX page

## - One
## - Two
## - Three

<Hello />
Enter fullscreen mode Exit fullscreen mode

As you can see, we are using MDX along with JSX inside the code. After this, when you run the Next app, you will be going to see the output as expected.

For sure, you can even integrate MDX with Vue, Vite, Gatsby, and other frameworks. To learn more about how to do this, visit here.

Extending MDX: Custom Components and Functionality

If you're using MDX content in your Next.js application, you may want to enhance its functionality beyond the default options. Luckily, extending MDX is simple. To get you started, here are a few examples of how you can extend MDX:

  • Create custom components: You can create your own components and use them within your MDX files. There are also many existing React components, such as PaulieScanlon/mdx-embed and system-ui/theme-ui, that you can leverage to add more functionality.

- Integrate with other plugins:
MDX can easily integrate with a variety of remark and rehype plugins, which allow you to do things like select and store code blocks, modify the HTML output of code blocks, and much more. There are even more plugins to change image sources, using charts, and all.

Moreover, you can easily generate React components to use in MDX directly from your designs file with

You can use the auto layout feature on Figma to make your designs responsive on the plugin and even if your designs don't utilise auto layouts, the plugin offers a Design Optimizer feature that uses AI to apply auto layouts to your design files. 

Once your designs are responsive, you can use the Auto Components feature to split your design elements into working React components, making them easy to extend.

What's more is that you can sync or export individual components, making them easily fit into your MDX files.

Hope you like it.

That's it - thanks.

Top comments (1)

tasin5541 profile image
Miftaul Mannan

My question would be, why? Why mix 2 languages in a codebase and in the same file? Doesn't really feel practical. If it was something that we could update after build, like updating a blog post, then that would make sense.