Back to posts
  • Marketing Websites
  • Maintenance

How We Future-Proofed a 6-Year-Old Website by Migrating From Gatsby to Remix

Daniel Becker
Daniel Becker
Abstract illustration of technologies kept and changed through a migration

Until recently, we had a client website running on Gatsby 2.

Development originally started six years ago. The static export of the website stood the test of time. And so did the original page structure, design, and content management system, all of which the client was still happy with.

However, the build system became increasingly fragile over the years, so it was time for a larger refactoring than our limited maintenance retainer could provide. We set out to replace the original frontend framework while keeping the content management system and other core technologies. This migration became a case study for digital sustainability and the joy of decoupling content from representation.

The Website’s History Link to this headline

When we started this website, the JAMStack approach was all the rage, promising faster, more secure websites with better performance. For our client, this meant the website could be hosted inexpensively while offering fast response times, directly contributing to higher engagement.

I remember browsing jamstack.org to evaluate which CMS to choose. A couple of popular headless CMS were already well-established, but there was still a lot of competition among self-hostable solutions—something we wanted at that time.

The Content Management System Link to this headline

The very first version of the website was build on top of Strapi . We encountered some issues with the official Strapi source plugin back then, so we replaced it with Cockpit by the sixth commit. We had used Cockpit for other projects at that time, so we knew we could get it up an running quickly. At that point, there was a source plugin available for Cockpit.

However, it turned out that development of this plugin had already stalled. As we were in a rush to get this website done we started to build a custom source plugin . That was a blessing in disguise. While it took time away from working on the actual product, it also allowed us to learn a lot about the inner workings of Gatsby, which we were about to use in many future projects.

Failing Builds Link to this headline

Over the years, this setup served us well, but the outdated Cockpit installation and custom build source plugin began to strain the limited maintenance retainer we had with the client. This situation highlighted the growing cost of technical debt—a challenge many businesses face as technology evolves.

The decision to migrate wasn’t just about updating the technology; it was about future-proofing the website, reducing the likelihood of costly emergencies, and ensuring the client could continue to rely on their website without unexpected disruptions.

The Migration Link to this headline

Before starting the actual migration, we gathered requirements to determine the best way forward. The major decision was which tech stack to migrate to, balancing client needs, time, and budget, as well as future costs related to hosting and our internal costs for maintaining the website.

Choosing a New Tech-Stack Link to this headline

We had a couple of requirements for the new setup, focusing on how to best serve the client’s needs:

  • The new setup should align with our current tech stacks, ensuring that ongoing maintenance is smooth and cost-effective for the client.
  • We wanted to keep the same content management system that the client was already comfortable with, avoiding any disruption in their daily operations.
  • The migration had to be seamless, maintaining the website’s look and feel so that end-users wouldn’t notice any changes.
  • Reducing build times was crucial, especially for image-heavy pages, so that updates could be deployed faster, leading to a more responsive and dynamic editing experience.

Our development team still works with React frequently, though most of our recent projects use SvelteKit. While we do have a starter setup that we usually use for new projects, it is based on SvelteKit . After a couple of attempts on refactoring code from React to Svelte we decided this was not feasible in the timeframe and budget we had at our disposal (yes, we asked GPT for help and yes, it did help and no, the process was mediocre at best). We are also running a couple of Remix sites, so we decided to try migrating from Gatsby to Remix.

Moving to Remix Link to this headline

Installing and configuring Remix to resemble the setup we had with Gatsby took just one afternoon. This included setting up a system that ensures the site always displays the latest updates without long wait times, using custom caching strategies for Incremental Static Regeneration (ISR).

Configuring the latest SCSS setup was straightforward, thanks to Remix using Vite as the development environment. We made the first data-fetching call using a reusable module to connect to Cockpit CMS, which we brought over from the old setup.

That was promising as we were seing a cached version of the homepage using data from the Cockpit CMS in half a day’s work. There still were a couple of things to take care of:

  • a lot of data wrangling to enable simple copy-and-paste of Gatsby pages files to Remix routes
  • migrating to TypeScript (where feasible)
  • loading, optimizing images

Data Fetching Link to this headline

We tackled this top to bottom. The data wrangling part would be the most complex and time-consuming part of this endeavour. In the Gatsby setup, we benefited from the build step. A process that gathered all the necessary data in advance, allowing us to easily link related information together before displaying it on the site. As we moved to a system that updates in real-time, we had to ensure this data processing could happen quickly enough to happen on the fly in case the page requested was not cached, yet.

Since we’re working with an older version of Cockpit, we have to retrieve data from the CMS sending multiple requests to the REST api for pages that feature relational data. We then have to piece the information together using custom transformer functions to resemble the structure we had fetched via GraphQL in the previous setup.

TypeScript Link to this headline

Migration to TypeScript was fairly straight forward as we could adopt it gradually, file by file. This played well with the overall process of migrating route by route. The homepage featured one dataset, so the data fetching was easy. It also included already a global layout that itself loads two or three components.

Each route that we migrated included a couple more components and step by step each route was loading more and more of already migrated components. Keeping React meant that almost all components worked out of the box and unblocking work on the data fetching.

In parallel we could refactor each component by adding TypeScript definitions, refactoring class based to function based components (where it made sense) and cleaning up, simplifying (S)CSS modules where CSS had caught up and functions had been deprecated.

Image Optimization Link to this headline

A big selling point of Gatsby back in the day was its built-in image optimization, which helped keep the website fast across devices. For our new setup, we considered using an image transformation service like imgix , but since the website is hosted on Vercel, we decided to leverage Vercel’s image optimization . This decision avoided introducing another service and potentially incurring additional hosting costs.

Having worked with unpic before, we decided to give it a try. Although Vercel wasn’t explicitely documented, it was mentioned in the list of supported CDNs .

It took a bit of fiddling around with the transformProps function of unpic/core as well as the vercel.json image configuration to make it work. Obvious in hind-sight but a hurdle when first setting this up, we had to pre-define and pass the same breakpoints to transformProps as for the Vercel image transformation config. We decided to not use the unpic component and instead just use unpic/core to build the srcset urls, taking care of sizing etc. ourselves.

What did we learn? Link to this headline

We originally chose to go with React, betting on its longevity and stability, and that bet paid off. By sticking with a widely supported technology, we were able to extend the life of the client’s website with minimal maintenance effort, which translates to significant cost savings over time. Gatsby’s stability, even on an outdated version, minimized the need for urgent fixes, allowing us to plan the migration carefully and avoid the high costs associated with rushed development work. This experience reinforces the importance of choosing technology that can adapt and grow with your business needs. The migration to Remix allowed us to modernize the codebase while maintaining the site’s core structure. We could reuse significant portions of the original codebase, saving both time and resources during the migration. The seamless transition has future-proofed the website while improving the editor experience and reducing the maintenance burden.

Custom Image Components Can Be Great Link to this headline

Vercel’s image optimization, though initially a risk due to limited documentation, proved to be a powerful tool in enhancing the website’s performance and user experience. Some frameworks come with sophisticated image components that are hard to style properly. Our custom solution, combined with unpic’s transformer functions, provided a lean and effective way to handle images—key to keeping both, the site’s original style definitions and fast image loading.

Moving Towards CSS Modules Link to this headline

The SCSS styling setup with its code co-located modules, keeps the styling code organized and easy to manage. It works seamlessly with the new tools we’re using, and not much has changed about it over the last few years, making it a reliable choice. In fact, moving to CSS modules without pre-processor seems within close reach. The SCSS features used are a couple of mixins but mostly variables and nesting. With CSS custom properties and native nesting we would only need to get rid of the mixins. Something we avoided in this iteration, as installing SCSS was easy enough. This still would be a great next step to further modernize this setup.

Sustainable Websites Through Headless CMS Link to this headline

While the migration was largely successful, some challenges remain, particularly in data fetching from the older Cockpit CMS. We recognize that the current setup could benefit from more structure. Nonetheless, the current solution is robust enough to deliver a reliable user experience, even under the constraints of an older CMS. Employing helper functions to measure the timing of Remix’s load functions allowed us quite a bit of optimization during development already. By now most data fetching is fast, even if the page was not cached already.

The old Content Management System is still running but definitely the part of the setup that requires updating next. When we first started this project the goal was to store data in a timeless structure that could be reused with future frontends. The seamless integration of this new website with the old CMS proves that the headless CMS approach, decoupling content management from representation, enables long-term success and maintainability.

In conclusion, this migration updated a six-year-old website with modern technologies in less than two weeks, laying the groundwork for future improvements. The project demonstrated the value of incremental modernization—leveraging existing strengths while embracing new advancements to ensure continued reliability.

  1. What is Incremental Static Regeneration (ISR) and why is it important?
    • Content Management Solution
    • Technical SEO

    Incremental Static Regeneration (ISR) is a technique that allows static sites to update their content without requiring a full rebuild. This is important because it combines the benefits of static site generation (like fast load times) with the ability to update content dynamically, providing the best of both worlds for modern web development.

  2. What is the benefit of using a headless CMS for long-term website success?
    • Content Management Solution
    • Structured Data Modelling

    A headless Content Management System (CMS) decouples content management from the front-end presentation layer, allowing updates or changes to the website’s technology without affecting the content or how it’s managed. This flexibility is crucial for long-term success, as it enables easier updates, faster site performance, and the ability to adapt to new technologies over time. It also enables multi-channel distribution from a single source of truth.

  3. How does a headless CMS contribute to sustainable web design?
    • Content Management Solution
    • Structured Data Modelling

    A headless CMS allows for content to be reused across multiple platforms and devices, reducing the need for redundant data storage and processing. This separation enhances flexibility and scalability, enabling developers to update or redesign the front-end without overhauling the content infrastructure. It also makes content management more efficient. Such an approach promotes long-term sustainability by reducing technical debt, easing maintenance, and allowing for seamless integrations with emerging technologies.

Editor

Daniel Becker
Daniel Becker

Co-Founder, Head of Tech

Connect on LinkedIn

Similar articles