🎄Migrating from GatsbyJS to NextJS🌟

Dec 22 2023

Back to 2023 Advent Calendar

Why migrate?

We've been using GatsbyJS for years for https://devtoolsdaily.com ;

It's been great for some time, but then we started having issues.

First, gatsby develop started taking 10 minutes and consume 100% CPU.

For some time we could get around with gatsby build and gatsby serve, but then this started throwing 'segmentation fault'.

Github issue on this topic showed no activity, so we started to look around.

Why NextJS?

While there are tons of new things we looked at like Vite(with Vike), vue, svetle etc. We decided to stich with something that is popular and won't go away suddently.

NextJS does come with Static Website support, which is what we needed.

How to migrate?

  1. Create a new NextJS project
  2. enable static site generation
// next.config.mjs
const nextConfig = {
    output: 'export',
}
  1. update all references to Router(e.g navigate) and Link, both are similar but have slightly different props.
  2. GatsbyJS has a few modes to create dynamic pages:
  • graphQL queries inside pages.
  • gatsby-node.js file with direct createPage function In NextJS we can use getStaticProps and getStaticPaths to achieve the same result. It's a little more straighforward and easier to understand. e.g
export async function getStaticPaths() {
    const paths: Array<any> = [];
    examplesBySlug.forEach((value, key) => {
        paths.push({ params: { slug: key } });
    });
    return { paths, fallback: false };
  }

  export async function getStaticProps({ params }: {params: {slug: string}}): Promise<StaticProps> {
    const exampleData = examplesBySlug.get(params.slug);
    return {
      props: {
        exampleData,
        title: `MermaidJS Example: ${exampleData?.label}`
      },
    };
  }
  1. gatsbyJS has tons of plugins, in NextJS you just have to find packages that help you achieve the same. for example:
  1. Populating SEO In Gatsby you could export Head component from each page.

In NextJS you just export getStaticProps and you can use them in Head in your _app.jsx

export function getStaticProps(): StaticProps {
    return { props: { description: metadata.description,
                      keywords: metadata.keywords, metaTitle: metadata.title } }
}
  1. Base Layout In GatsbyJS to use layout you had to just wrap into Layout in your pages.

In NextJS you can apply layout in app.jsx. and if you need another layout, you can just pass a flag to app.jsx via 'getStaticProps'

e.g

export default function App({ Component, pageProps }) {
  ...
      {pageProps.noLayout ? <Component {...pageProps} /> : <PageLayout pageProps={pageProps}>
        <Component {...pageProps} />
      </PageLayout>}
  ...