Migrating My Blog from GatsbyJS to NextJS

I began my blogging journey in high school, starting with blogger.com
, where I created my first blog, wrote a few popular posts, and saw my first wave of visitors. As I explored more options, I moved to wordpress.com
for its better UI and additional features.
A few years later, I switched to Gatsby for its simplicity, markdown-based structure, and GraphQL integration, which made it a great choice for static websites. Now, after another few years, I've migrated once again—this time to NextJS.
This post shares my experience migrating my blog from Gatsby to NextJS. It wasn’t a straightforward process, but it was a valuable learning journey.
Why NextJS?
There are several reasons why I decided to migrate my blog to NextJS. While Gatsby is a great platform for static websites, maintaining it became increasingly difficult and complex. To be honest, I never fully understood how it worked—I was just following random tutorials whenever I added new features, which eventually turned my blog into a messy, unstructured project. This lack of understanding went against the core principles of engineering.
Why not just go back to the basics and learn from the documentation? I could have, but for couple of reasons i was hesitant to do it.
Another major reason was that my blog was two major versions behind the latest Gatsby release. Learning an outdated version wasn't a wise investment, and many of the dependencies and plugins I relied on were either deprecated or no longer maintained. Upgrading to a newer Gatsby version wasn't straightforward either.

On the other hand, I've been learning NextJS in my free time, and rebuilding my blog with it seemed like a great way to apply my knowledge and practice.
Lastly, I'm fascinated by the world of SaaS, and the idea of building my own product excites me. Moving to NextJS feels like a step in the right direction, giving me the flexibility to experiment and grow.
Tech Stack
For this particular website, i use the following tech stacks:
- NextJS: Framework for building server-side rendered (SSR) React applications.
- TailwindCSS: Utility-first CSS framework for rapidly building custom designs.
- TypeScript: Static type system for JavaScript that adds compile-time type checking.
- Vercel: Platform for serverless, edge-optimized web applications.
- DaisyUI: TailwindCSS component library.
- MDX: Markdown-based JavaScript library that allows you to write JSX in your markdown files.
- PostHog: Analytics tool for tracking website traffic.
These are just some of the key libraries powering this website.
Migration Process
The migration process wasn't too complicated since the core functionality was simply rendering blog posts from markdown files. However, ensuring that all the MDX plugins I previously used worked seamlessly in NextJS was a bit of a challenge. In cases where certain plugins weren't compatible, I had to find suitable alternatives or write custom plugins.
Start With The Blog Example
The first step in my migration was exploring NextJS examples for building a blog. I came across the Portfolio Starter Kit by Vercel, which provided a simple and well-structured example. This template was a great starting point for understanding how to create static pages in NextJS.
Moving to MDX
In my previous blog, I used .md
files for my posts, but I decided to switch to .mdx
for its added flexibility and support for embedding React components. Migrating the content was straightforward—technically, renaming .md
files to .mdx
works in most cases.
However, some of the markdown syntax I previously used wasn't directly compatible with MDX. To resolve this, I created custom React components to replicate the behavior of those special markdown elements. With MDX, I can now directly import and use components within my blog posts, making my content more interactive and customizable.
Here's an example of one such component used in my blog:
export const Note = ({ children, className }: { children: React.ReactNode; className?: string }) => {
return (
<div role='alert' className={cn("not-prose alert alert-info alert-soft py-6", className)}>
<span className='text-sm/6'>{children}</span>
</div>
);
};
To use this, i just need to import the component and use it in the mdx file:
import { Note } from "@/components/blog/mdx/Alerts";
<Note>This is a note</Note>;
it will render a component like this:
I am using NextJS 14 and by default it already supports mdx. This means i don't need to install additional libraries to make mdx work in NextJS.
MDX Plugins
In my previous setup, I relied on several Gatsby Remark and Rehype plugins. Since NextJS uses a different ecosystem, I had to find equivalent plugins that worked with MDX in NextJS. Technically not all, some of the remark plugins works just fine on NextJS. It took some time, but I eventually found suitable alternatives.
NextJS 14 allows adding MDX plugins directly in the next.config.mjs
file. This makes it easy to integrate Remark and Rehype plugins like this:
/** @type {import('next').NextConfig} */
const nextConfig = {
// your next config
...
};
const withMDX = createMDX({
options: {
remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter, remarkEmoji, remarkExportHeadings, remarkGfm],
rehypePlugins: [[rehypePrismPlus, { ignoreMissing: true }], rehypeSlug],
},
});
export default withMDX(nextConfig);
The UI and Pages
For the design, I use a combination of Tailwind CSS and DaisyUI. I followed a mobile-first approach, ensuring the website is fully responsive and works seamlessly across different devices.
Since I built the website from scratch, I have complete control over the UI and page structure. This allows me to design it exactly the way I want while keeping it simple and minimalistic. More importantly, I know where everything goes, making future customizations easy—which is pretty cool!
Added sidebar
Previously, my blog had a simple single-layout design, but I wanted to introduce a sidebar to include additional information. I haven't fully decided what to put there yet, but I'll figure it out as I go.
For now, I've added a table of contents to the blog post detail page and a placeholder "Popular Posts" section in the sidebar. Why a placeholder? Just to avoid an awkward empty space—haha!
Deployment
I previously used Netlify for deploying my Gatsby blog, but since I migrated to NextJS, I switched to Vercel for deployment. The process was smooth and straightforward.
I also had to update my DNS settings, which I managed through my domain provider, Squarespace (formerly Google Domains). One thing I love about Vercel is its simplicity—I just push my code, and it automatically triggers a deployment.
Monitoring and Analytics
Previously, I used Google Analytics to track website traffic, but I wanted to try something new. I came across PostHog, which looked promising, so I decided to give it a shot.
Setting up PostHog was straightforward, and I found its UI much more intuitive compared to Google Analytics. While it's not entirely free, it offers 1M events per month for free, which is more than enough given my website's current traffic.
Conclusion
Migrating from Gatsby to NextJS wasn't too complicated, and I believe it was a great decision. The process taught me a lot, not just about migration but also about the features in NextJS. Overall, it was a rewarding learning experience!