Nextjs Mdx is a powerful tool for creating customizable blogs, and one of its key features is the ability to use MDX files for content.
MDX files are a combination of Markdown and JSX, allowing you to write HTML-like code in your Markdown files.
This flexibility makes it easy to add custom components and layouts to your blog posts.
You can create a new MDX file in your Nextjs project by running the command `npx create-next-app my-app --template with-mdx`.
This will set up a basic Nextjs project with MDX support, allowing you to start building your blog right away.
What is MDX?
MDX is a markup language that supports the use of JSX within Markdown documents. It combines the simplicity of Markdown with the power of React components.
Markdown is a syntax that allows us to format text for a web page, and it's popularly used to natively edit messages via services like WhatsApp and Mattermost.
MDX is a more feature-full version of Markdown that allows you to embed JSX in Markdown, making it possible to create interactive and dynamic content.
Typically, MDX is used for content that requires both rich formatting and interactivity, such as documentation or blog posts.
By allowing React components to be embedded directly into a Markdown document, MDX simplifies the creation of dynamic content that would be difficult to achieve with simple Markdown.
MDX is supported by several libraries and frameworks, including Next.js, Gatsby, Nuxt, and other static site generators.
Getting Started
Let's kick off our Next.js MDX project by setting up a new application. Run the command in your terminal to create a new project with an interactive menu of options, and make sure to select the app router.
To get started, you'll need to install next-mdx-remote, which will allow us to compile MDX files into React elements. Run the command to install it, and don't worry if you encounter errors in VSCode - you can resolve this issue by selecting the "Use Workspace Version" option from the menu.
Introduction
Building a Next.js blog can be a fun and rewarding experience, and it starts with setting up a basic Next.js application with TypeScript. This will be the foundation of our project.
MDX integration is a powerful feature that allows us to write JSX directly in our Markdown files, enabling rich and interactive experiences in our blog posts. This is made possible by the next-mdx-remote library.
We'll be utilizing the app router and React server components to create a statically generated page to display all our blog posts, sorted from newest to oldest. This will be a key part of our project.
The cache function in React allows us to memoize the result of a function when called from a server component, enabling the reuse of the result whenever the function is called with the same arguments. This is similar to how Next.js caches the result of a fetch.
Installing Dependencies
To get started with your Next.js project, you'll need to install the required dependencies. This includes the path library, which helps you get directories from the file system, and the fs library, which is used to read directories and files.
You'll also need the gray-matter library to extract front matter from files. Front matter is a block of metadata placed at the beginning of a Markdown file, which helps define metadata such as title, author, and date.
Here are the specific libraries you'll need:
- path
- fs
- gray-matter
- next-mdx-remote
To install these packages, run the following command in your terminal:
To use MDX with Next.js, you need to install the next-mdx-remote library, which will parse the MDX content to generate it as a React component.
If you're using TypeScript, make sure to select the "Use Workspace Version" option from the menu in VSCode to resolve any errors you may encounter.
Creating Pages
Creating pages in Next.js MDX is a breeze. You can create a page with MDX by opening https://localhost:3000/ and all the posts you added will be rendered.
To dynamically generate routes, you need to set up static generation for dynamic routes. This is done by exporting a function named generateStaticParams in page.tsx. This function constructs an array of parameters containing the slug of each post based on the filename in the markdown folder.
The server component can then use these slugs to fetch the content of the respective MDX file. To keep code clean, you can create a file called mdxUtils that contains various helper functions.
Creating a Page
Creating a page is a straightforward process. To get started, you can use a tool like Next.js, which allows you to create pages with MDX.
With Next.js, you can create a page by following the instructions provided. For example, you can open https://localhost:3000/ and see the posts you added rendered on the page.
Rendering Your Posts
To render your posts, you'll need to set up MDX with remark and rehype plugins. This is where you can customize the components you want to use in your markdown files.
You'll want to use the official next/link and next/image components to enable client-side routing and image optimization. I've defined custom components like file trees in this post.
You can add the intended image width and height to the image URL as query parameters, allowing you to pass the width and height to next/image. This is how I've accomplished it.
You can choose to build all of your posts at build time by adding generateStaticParams to the page.
Static Generation for Dynamic Routes
Static generation for dynamic routes allows you to generate pages at build time, rather than on-demand at request time. This can improve performance and reduce server load.
To set this up, you'll need to export a function named generateStaticParams in your page file. This function will enable static generation for dynamic routes.
Within generateStaticParams, you'll construct an array of parameters containing the slug of each post based on the filename in the markdown folder.
You can organize this by creating a file called mdxUtils, which will contain various helper functions. One of these functions will be getPostFilePaths, which returns an array of all the paths of the markdown files inside the markdown folder.
The getPostFilePaths function is used inside generateStaticParams to get the paths of the markdown files. The name of each markdown file, without its extension, is used as the slug.
A different page will be generated at build time for each slug, with the slug passed as a parameter to each of these pages.
Rendering Content
Rendering content in Next.js MDX is a breeze. You can fetch and render markdown from a remote source, like a CMS, using next-mdx-remote and its experimental React Server Components support.
To render your posts, you'll need to set up MDX with remark and rehype plugins. You can pass in custom components using the components={mdxComponents} prop, which is where you'd use the official next/link and next/image components for client-side routing and image optimization.
You can optionally build all your posts at build time by adding generateStaticParams to the page. This allows you to pre-render your content, making it faster for users to access.
To fetch the markdown content, you'll need to use a function like getCompiledMDX, which returns typed frontmatter data. You can then use this data to render the title, date, and image, and finally render the content of the MDX file.
If you want to serve the image locally, you'll need to place it in the public folder. For example, if you have an image named my-image.png placed directly inside the public folder, you would pass the path /my-image.png to the Image component's src property.
Customization
Customization is a breeze with Next.js MDX. You can integrate custom React components and use them in MDX files just like in JSX.
To achieve this, simply pass the components within the components property of the compileMDX function. This gives you the flexibility to override default rendered elements with your own custom implementations.
If your custom component relies on client-side functionality, don't forget to include the "use client" directive at the top of its file, otherwise it won't work. This is crucial for components that use hooks like useState or browser APIs like localStorage.
Generating Metadata
Customization allows us to tailor our blog post pages for better SEO and social media sharing. To improve the SEO of our blog post page, we can add metadata using the generateMetadata function, which accepts the slug from the page's parameters.
Using the slug, we can retrieve the frontmatter data and construct a metadata object. This object includes a meta title, description, and additional Open Graph properties that control how our content is displayed on social media platforms.
Open Graph is a protocol that allows websites to control how their content is displayed when shared on social media platforms. By utilizing Open Graph properties, we can ensure our blog posts look great when shared on social media.
Extracting Code
Extracting code from a theme or plugin can be a bit tricky, but it's a crucial step in customization.
You can use a code editor or IDE to extract the code, and it's a good idea to work in a local environment to avoid any conflicts with the live site.
The WordPress Codex has a section on extracting code from a theme, which can be a helpful resource.
A good place to start is by identifying the specific files you need to extract, such as the functions.php file or the styles.css file.
By extracting the code, you can then customize and modify it to fit your needs.
It's also a good idea to use a version control system, such as Git, to keep track of any changes you make to the code.
Building an MDX Blog
Building an MDX blog with Next.js involves creating a new project using the `npx create-next-app` command.
To start, you'll need to install the `@mdx-js/tag` package, which allows you to use MDX tags in your Next.js project.
Next.js MDX blogs are often configured using the `pages/_app.js` file, where you can set up the MDX provider and other global configurations.
MDX files in Next.js are typically written in a `.mdx` extension and can contain a mix of Markdown and JavaScript code.
With Next.js MDX, you can also use the `useMDXComponent` hook to render MDX components dynamically.
MDX files can be imported and used as components in your Next.js pages, making it easy to reuse content across your blog.
Code and RSS
I've implemented a custom solution for generating an RSS feed in my Next.js MDX project.
I use the marked library to parse the markdown files.
The marked library is used to parse the markdown files, which allows me to pass the JSX components for MDX through to the RSS feed.
This means the components are rendered in the RSS feed, making them legible even when not rendered in the usual way.
I ensure the components are legible by trying to make them readable even when not rendered.
Sources
- https://mattermost.com/blog/create-a-next-js-blog-on-vercel-using-mdx-and-tailwindcss/
- https://maxleiter.com/blog/build-a-blog-with-nextjs-13
- https://dimitrisanastasiadis.com/blog/how-to-create-a-blog-with-nextjs-and-mdx
- https://www.codemotion.com/magazine/frontend/how-to-create-an-mdx-blog-in-typescript-with-next-js/
- https://claritydev.net/blog/copy-to-clipboard-button-nextjs-mdx-rehype
Featured Images: pexels.com