Adding MDX Blogs Section
Adding a blogs section to a Next.js website using MDX.
- Published
- Filed under
- Technology
- Reading
- 3 min
Motivation
I wanted to write blogs to document what I’ve been learning every day. To achieve this, I set out to find a suitable platform. Since I already had a website built with NextJS, I thought I could simply add a blog section to it. I assumed there must be a tool that would allow me to do so.
I discovered tools like Contentful and Payload, which can be integrated into any website or used to create a new one. These tools enable the construction of complex websites, which seemed overkill for my task. All of them work by implementing MDX in Next.js. They promised to integrate with existing code, but I found the documentation lacking and difficult to follow. They also required their own folder structure, which meant I would have to rebuild my entire website from scratch if I used them.
To avoid this complexity, I decided to implement an MDX processor on my own. This approach reduced the complexity significantly and gave me full control over what I wanted to display and how I wanted to show it.
CMS Tools that I found to be overkill:
Closed Source:
Open Source:
Implementing MDX in my website
Start by creating a route just like you normally would. This included a page to list all the blogs and another to display each one individually. The NextJS page has a good guide on how to do this.
Styling this page was a bit tricky because I wanted it to match the look of my existing website and keep things consistent for users. I couldn’t find the right tools to make it happen, so I ended up using Tailwind CSS classes to get the job done.
I ended up using existing tailwind classes to style each element. This was a bit tedious, but it worked well for my needs.
const components = {
h1: (props: any) => (
<h1 className="text-3xl font-bold mt-8 mb-6 sm:text-4xl" {...props} />
),
h2: (props: any) => (
<h2 className="text-2xl font-semibold mt-6 mb-4 sm:text-3xl" {...props} />
),
h3: (props: any) => (
<h3 className="text-xl font-semibold mt-5 mb-3 sm:text-2xl" {...props} />
),
h4: (props: any) => (
<h4 className="text-lg font-semibold mt-4 mb-2 sm:text-xl" {...props} />
),
h5: (props: any) => (
<h5 className="text-md font-semibold mt-3 mb-2 sm:text-lg" {...props} />
),
h6: (props: any) => (
<h6 className="text-sm font-semibold mt-3 mb-2 sm:text-md" {...props} />
),
p: (props: any) => (
<p className="text-base leading-relaxed my-4 sm:text-lg" {...props} />
),
a: (props: any) => (
<a
className="dark:text-zinc-300 hover:underline break-words max-w-full"
{...props}
/>
),
code: (props: any) => (
<code
className="px-2 py-1 rounded bg-gray-100 dark:bg-zinc-800 text-sm font-mono break-words max-w-full"
{...props}
/>
),
pre: (props: any) => (
<pre
className="p-4 rounded-md my-4 bg-gray-100 dark:bg-zinc-800 text-sm overflow-x-auto max-w-[calc(100vw-3rem)]"
{...props}
/>
),
img: (props: any) => (
<Image
{...props}
alt={props.alt}
width={600}
height={300}
className="rounded-lg mx-auto"
/>
),
ul: (props: any) => (
<ul className="list-disc pl-6 my-4 space-y-2" {...props} />
),
ol: (props: any) => (
<ol className="list-decimal pl-6 my-4 space-y-2" {...props} />
),
li: (props: any) => (
<li className="text-base leading-relaxed sm:text-lg" {...props} />
),
blockquote: (props: any) => (
<blockquote
className="border-l-4 border-blue-500 pl-4 my-4 italic text-gray-600 dark:text-gray-300"
{...props}
/>
),
};
Pass the components to the MDXRemote:
<MDXRemote {...mdxSource} components={components} />
And volia 🎉, you have a blog section on your website!.
Let me know if you have any questions or need help with this. I would be happy to help you out! To see the raw source of this blog add .mdx to the URL.
Caio 👋