In the dynamic world of web development, the ability to seamlessly integrate and display various types of content is crucial. Imagine building a blog where you want to write posts using Markdown, a lightweight markup language that’s easy to read and write. Or perhaps you’re creating a documentation site where content is formatted in Markdown for simplicity and maintainability. This is where react-markdown, a powerful npm package, comes into play. It allows you to transform Markdown text into interactive React components, making dynamic content integration a breeze in your Next.js applications.
Why React-Markdown and Next.js?
Next.js, with its server-side rendering (SSR) and static site generation (SSG) capabilities, is an excellent choice for building performant and SEO-friendly websites. Combining Next.js with react-markdown offers a perfect synergy. You can:
- Improve SEO: Render Markdown content on the server, ensuring search engines can easily crawl and index your content.
- Enhance Performance: Reduce the load on the client-side by pre-rendering content.
- Simplify Content Management: Allow content creators to use Markdown, a user-friendly format, without needing HTML knowledge.
- Boost Development Speed: Use a well-maintained and widely adopted library to handle Markdown parsing.
Setting Up Your Next.js Project
Before diving into react-markdown, ensure you have a Next.js project set up. If you don’t, create one using the following command:
npx create-next-app my-markdown-app
Navigate into your project directory:
cd my-markdown-app
Installing react-markdown
Now, install the react-markdown package and any necessary dependencies:
npm install react-markdown
You may also need to install a Markdown parser, such as remark-gfm, to support GitHub Flavored Markdown (GFM) features like tables, task lists, and more:
npm install remark-gfm
Basic Usage
Let’s create a simple page to display Markdown content. Create a new file, for example, pages/markdown-page.js, and add the following code:
import ReactMarkdown from 'react-markdown';
function MarkdownPage() {
const markdownContent = `
# Hello, Next.js with React-Markdown!
This is a paragraph of text.
- Item 1
- Item 2
```javascript
console.log('Hello, world!');
```
`;
return (
<div>
{markdownContent}
</div>
);
}
export default MarkdownPage;
In this code:
- We import
ReactMarkdownfrom thereact-markdownpackage. - We define a
markdownContentvariable containing Markdown text. - We use the
ReactMarkdowncomponent, passing themarkdownContentas a child.
Run your Next.js development server:
npm run dev
Open your browser and navigate to http://localhost:3000/markdown-page. You should see the rendered Markdown content.
Styling Your Markdown
Out of the box, react-markdown renders basic HTML elements. However, you’ll likely want to style the output to match your website’s design. There are several ways to do this:
1. Using CSS
You can use standard CSS to style the rendered HTML elements. For example, to style headings:
/* styles/markdown.css */
h1 {
color: navy;
}
/* Apply these styles in your component */
Import this CSS file into your component:
import ReactMarkdown from 'react-markdown';
import '../styles/markdown.css'; // Import the CSS file
function MarkdownPage() {
// ... (rest of the code)
}
export default MarkdownPage;
2. Using CSS Modules
For more modular styling, use CSS Modules. Create a CSS Module file (e.g., markdown.module.css):
/* styles/markdown.module.css */
.heading {
color: darkgreen;
}
Import the CSS Module into your component:
import ReactMarkdown from 'react-markdown';
import styles from '../styles/markdown.module.css'; // Import the CSS Module
function MarkdownPage() {
const markdownContent = `# Hello, Styled Markdown!`;
return (
<div>
<h1>{children}</h1>,
}}
>
{markdownContent}
</div>
);
}
export default MarkdownPage;
In this example, we use the components prop of ReactMarkdown to override the rendering of the h1 tag and apply the CSS class from the CSS Module.
3. Using a CSS-in-JS library
Libraries like styled-components or Emotion provide a more dynamic and JavaScript-centric approach to styling. Here’s an example with styled-components:
import ReactMarkdown from 'react-markdown';
import styled from 'styled-components';
const StyledHeading = styled.h1`
color: purple;
font-size: 2em;
`;
function MarkdownPage() {
const markdownContent = `# Hello, Styled Markdown!`;
return (
<div>
{children},
}}
>
{markdownContent}
</div>
);
}
export default MarkdownPage;
Handling Images
Images are a common part of Markdown content. react-markdown handles them by default, but you might want to customize their rendering. For instance, you might want to add a class for responsive styling.
import ReactMarkdown from 'react-markdown';
function MarkdownPage() {
const markdownContent = `

`;
return (
<div>
(
<img src="{src}" alt="{alt}" />
),
}}
>
{markdownContent}
</div>
);
}
export default MarkdownPage;
You would then define the .responsive-image class in your CSS to make the images responsive.
Adding Code Highlighting
When displaying code blocks, syntax highlighting improves readability. You can integrate a code highlighting library like rehype-prism (which uses Prism.js) or rehype-shiki (which uses Shiki, a modern syntax highlighter based on VS Code’s textmate grammars) with react-markdown.
Here’s an example using rehype-prism:
- Install necessary packages:
npm install rehype-prism @mdx-js/react rehype-raw
- Configure your component:
import ReactMarkdown from 'react-markdown';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import rehypeRaw from 'rehype-raw';
import remarkGfm from 'remark-gfm';
function MarkdownPage() {
const markdownContent = `
```javascript
console.log('Hello, world!');
```
`;
return (
<div>
<ReactMarkdown
children={markdownContent}
remarkPlugins={[remarkGfm]}
rehypePlugins={[rehypeRaw]}
components={{
code({node, inline, className, children, ...props}) {
const match = /language-(w+)/.exec(className || '')
return !inline && match ? (
) : (
<code>
{children}
)
}
}}
/>
