GSD

Migrating a Marketing Site from Gatsby to Next.js: A Technical Guide

Posted by Jake Lumetta on October 24, 2023

Migrating your site from Gatsby to Next.js can be a smooth process if you follow the right steps. Both frameworks use React, so much of your component code can remain unchanged. The primary differences arise in the way they handle data fetching, routing, and optimization.

Migrating from Gatsby to Next.js (step-by-step)

1. Setting Up Next.js

Start by setting up a new Next.js project:

npx create-next-app your-nextjs-app
cd your-nextjs-app

2. Migrating Static Pages

For static pages, you can move your Gatsby components into the pages directory of your Next.js project.

Example: Move src/pages/about.js in Gatsby to pages/about.js in Next.js.

3. Handling Routing

In Gatsby, links between pages are handled using gatsby-link. In Next.js, you use the Link component from next/link.

Replace:

import { Link } from "gatsby"
<Link to="/about/">About</Link>

With:

import Link from 'next/link'
<Link href="/about">About</Link>

4. Data Fetching

One of the biggest differences between Gatsby and Next.js is how they handle data. Let's delve deeper with a more detailed example.

Data Fetching in Gatsby:

In Gatsby, data is primarily fetched at build time using GraphQL. Let's consider a Gatsby site that fetches a list of products from a hypothetical CMS.

import { graphql } from "gatsby";
import Product from "../components/Product";


export default function ProductsPage({ data }) {
  return (
    <div>
      {data.allProducts.edges.map(edge => (
        <Product key={edge.node.id} product={edge.node} />
      ))}
    </div>
  );
}


export const query = graphql`
  query {
    allProducts {
      edges {
        node {
          id
          name
          price
          imageUrl
        }
      }
    }
  }
`;

Data Fetching in Next.js:

Next.js provides several methods for data fetching:

  • getStaticProps: Fetch data at build time (similar to Gatsby's default behavior).

  • getServerSideProps: Fetch data at request time on the server.

  • getStaticPaths: Used with getStaticProps for dynamic routes to specify which paths to pre-render.

For our example, let's assume we want the same build-time behavior as Gatsby, so we'll use getStaticProps.

Next.js Code:

Firstly, set up your API call. You might use fetch or libraries like axios. Here's an example using fetch:

// pages/products.js
import Product from "../components/Product";


export default function ProductsPage({ products }) {
  return (
    <div>
      {products.map(product => (
        <Product key={product.id} product={product} />
      ))}
    </div>
  );
}


export async function getStaticProps() {
  // Fetch data from a hypothetical CMS API endpoint
  const res = await fetch("https://api.example.com/products");
  const products = await res.json();


  // Return the fetched data as props
  return {
    props: {
      products,
    },
  };
}

Notes:

  1. The Gatsby example uses GraphQL, while the Next.js example uses a RESTful API call. If your data source provides a GraphQL endpoint, you can still use GraphQL in Next.js with libraries like Apollo Client.

  2. In the Next.js example, data fetching logic resides in the getStaticProps function. This function runs at build time and provides fetched data as a prop to the component.

  3. If you wanted real-time data on each request, you'd use getServerSideProps instead of getStaticProps.

Transitioning between Gatsby's GraphQL-based data layer and Next.js's more flexible data fetching methods might require rethinking how you interact with your data sources. Ensure you understand the needs of your application (static vs. dynamic data) and choose the appropriate data fetching strategy in Next.js.

5. Handling Images

Gatsby offers the gatsby-image for optimized image loading. Next.js has its own solution called next/image.

Replace:

import Img from "gatsby-image"
<Img fixed={data.file.childImageSharp.fixed} />

With:

import Image from 'next/image'
<Image src="/path/to/image.jpg" width={500} height={500} />

6. SEO

Gatsby has plugins like gatsby-plugin-react-helmet for SEO. In Next.js, you can use the built-in Head component.

Replace:

import { Helmet } from "react-helmet"
<Helmet title="My Title" />

With:

import Head from 'next/head'
<Head>
  <title>My Title</title>
</Head>

7. Plugins & Libraries

Review your Gatsby plugins. Some might not be needed in Next.js, while others might have Next.js alternatives. For instance, if you're using gatsby-plugin-styled-components, you'd replace it with babel-plugin-styled-components for Next.js.

8. Deployment

While Gatsby sites are often deployed as static sites (e.g., on Netlify or Vercel), Next.js offers both static generation and server-side rendering. Choose the right deployment solution based on your needs.

Example: If you're using Vercel, simply run:

Vercel
Learn how ButterCMS can streamline your content management.
Start my free trial

Key Considerations to keep in mind when migrating from Gatsby to Next.js

  • Performance Benchmarks: Before starting the migration, gather performance metrics of your Gatsby site using tools like Google Lighthouse, WebPageTest, or Chrome DevTools. Once you've migrated to Next.js, re-test to compare the results. This will help you understand the impact of the migration on the site's performance.

  • SEO Implications: Ensure that the transition doesn't negatively impact your search engine rankings:

    • Preserve URLs: Avoid changing page URLs during the migration. If URLs must change, implement 301 redirects.

    • Migrate Metadata: Ensure meta tags, schema.org data, and other SEO-relevant content is transferred correctly.

    • XML Sitemaps & Robots.txt: Update these if necessary, especially if your URL structures change.

  • Third-party Integrations: Check for compatibility of third-party tools or services (like CMS, eCommerce systems, or analytics tools) with Next.js. Some Gatsby plugins might not have direct equivalents in Next.js, so you might need to find new solutions or integrations.

  • Testing:

    • Functional Testing: Ensure all functionalities, like forms, authentication, and interactive elements, work as expected.

    • Visual Regression Testing: Use tools like Percy or BackstopJS to check for unintended visual changes post-migration.

    • Cross-browser and Cross-device Testing: Make sure the site functions well across different browsers and devices.

  • Iterative Deployment: Consider deploying the migrated site in stages or using feature flags. This way, you can test the waters without fully committing until you're sure everything works as expected.

  • User Feedback: Once you've migrated, gather feedback from users. They might spot issues that you missed.

  • Continuous Integration and Deployment (CI/CD): Update your CI/CD pipelines to accommodate the Next.js build and deployment process, especially if you're using server-side rendering.

  • Training: If you work in a team, ensure that all members are trained or familiarized with Next.js. This includes developers, content creators, and even the marketing team if they interact with the site's backend.

  • Documentation: Update any technical documentation to reflect the changes from Gatsby to Next.js. This includes architecture diagrams, codebase documentation, and development guidelines.

  • Cost Implications: If you're moving from a static Gatsby site to a server-rendered Next.js application, there might be additional server costs. Plan and budget accordingly.

  • Backup: Always maintain a backup of the Gatsby site until you're sure the migration is successful. This provides a safety net in case anything goes wrong.

  • Community and Support: Remember that both Gatsby and Next.js have active communities. If you run into challenges, consider seeking advice or solutions from community forums, Discord channels, or GitHub discussions.

By paying attention to these considerations, developers can ensure a more holistic and trouble-free migration process.

Final thoughts

While there are differences between Gatsby and Next.js, the migration process can be straightforward if approached methodically. Take the time to understand the nuances of each framework, especially around data fetching and plugins, to ensure a successful migration.

Make sure you receive the freshest Butter tutorials and product updates.
Jake Lumetta

Jake is the CEO of ButterCMS. He loves whipping up Butter puns and building tools that make developers' lives better.

ButterCMS is the #1 rated Headless CMS

G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award G2 crowd review award

Don’t miss a single post

Get our latest articles, stay updated!