Objectives
- Rendering markdown in an Next.js project
- Use custom components
- Add Remark and Rehype plugins
- Learn to change states in parent component from child.
- Have fun 🔥
Visit the finished build here
1. Create the landing page
I want a simple layout so I divided the screen into two parts
- Left side: editor
- Right side: markdown preview
2. Add states to store data
Now let's change it into a client component and add the useState
hook.
3. Setup dependencies for Markdown
We use react-markdown to render markdown and @tailwindcss/typography to style the markdown. Install them by firing the following commands.
Now import and add the Markdown component and pass source
as children. Remember to add the prose
classname to the Markdown component.
Now if you type any markdown you'd still not find any changes.
We forgot to add the @tailwindcss/typography
plugin to the tailwindcss config 💀
Change your tailwind.config.ts
to the following:
Now write some markdown and you will see the changes live 🚀
4. Code Highlighting and Custom Components
Now we need to install the react-syntax-highlighter
package to add code highlighting to our project.
Now we are going to create a Custom Component for the Code Highlighter.
Create a folder called components
inside the src
folder. Now create a file called Code.tsx
inside the components folder.
Add the following code from the documentation of react-syntax-highlighter:
Here the props contain a classname with the language of the code in the format: lang-typescript
or sometimes language-typescript
so we use some regex grooupsto remove everything except the name of the language. The not-prose
classname is going to remove the default typography styles.
Now comeback to the main page.tsx
file and import the CodeBlock
component and pass it to the original <Markdown />
component
This is going to replace every occurrence of code
with our Custom CodeBlock
component.
(Optional)
BUG (🐛): You might have a weird dark border around your code component which is caused by the pre
tag and tailwind styles.
To fix this go back to your Code.tsx
and add the following code that removes the tailwind styles from the pre tag.
Import this into your page.tsx
and add it into the options
variable:
This is going to remove that border.
5. Adding Rehype and Remark Plugins
Rehype and Remark are plugins used to transform and manipulate the HTML and Markdown content of a website, helping to enhance its functionality and appearance.
We are going to use the following:
rehype-sanitize
: Sanitize the markdownrehype-external-links
: Add an 🔗 icon on linksremark-gfm
: Plugin to support GFM (Supporting tables, footnotes, etc.)
Install the Plugins:
Back to our page.tsx
Pass the remark plugins within remarkPlugins
and rehype plugins in rehypePlugins
(I know very surprising).
If any plugin needs any customization put them in square brackets followed by the plugin name and the options in curly brackets in this syntax:
[veryCoolPlugin, { { options } }]
6. Header with Markdown buttons
Next we add a Header component that has buttons which on clicked inserts certain Markdown elements.
First create a Header.tsx
in the components
folder and write the following code:
Import it in the main page.tsx
Now here's the catch. Our states lie in the parent component and the Header
is a child component.
How do we work with the states in the child component? The best solution is we create a function to change the state in parent component and pass the function to the child component. Read this article
In Header.tsx
we need to accept the function as a parameter and add it to the button using the onClick
attribute:
Back to page.tsx
we pass the feedElement
function to the Header
Now anytime you click on a button you should get the following Markdown Element.