When our team decided to modernize this platform, I understood it wouldn’t be a small feat. Mostly because this project involves developing and managing a multilingual travel website with extensive content and a global audience. We’ll be discussing Rove.me — a travel guide that helps its users by suggesting the best time to visit a destination and the most vibrant experiences they can get there.
About the project
Rove.me is a brainchild of Rebbix Labs aimed at helping travellers get the best out of their trip by taking into account seasonality, weather data, and crowdedness while planning their vacations. The website is content-driven and accessible in 6 languages, always requiring consistent efforts to boost and maintain high SEO metrics. The frontend was built with React, utilizing server-side rendering (SSR) implemented through the Koa framework, with the codebase written in JavaScript. Rove.me website was primarily designed with a desktop-first approach, even though 70% of the traffic originated from mobile devices.
In 2023, our team decided to update the website’s interface, implementing new frontend technologies. In this article, I’d like to share our journey to a new Rove.me website. Let’s see which goals we had for this transition, which obstacles we’ve overcome, and the benefits we achieved as a result.
Reasons behind the upgrade
When I started working on the project, there were several issues that prompted us to look for new, more effective solutions.
- Slow implementation of updates
Even simple frontend tasks, such as adding the date of publishing the article below its title, for example, took me days to implement. It wasn’t clear where in the project library should I look for the feature in question and which consequences the changes would bring about.
- UX/UI glitches
On mobile devices, users often experienced a noticeable issue where the content would initially load, then disappear, and re-render within a second. This caused a 'blinking' effect, as illustrated below, with no clear explanation for that.
- Complications in development
To implement or update an interface, I had to launch the entire stack, including the database, servers, and cache, which was both time-consuming and inconvenient. Additionally, there was no efficient system for storing translations — large JSON files were used instead. Given that the website supports six languages, this further complicated working with internationalization.
After analyzing these issues, we came to the conclusion that an out-of-the-box solution could handle all those routine tasks, saving tons of developer time and effort.
Approach to choosing a framework
Selecting the right framework for revamping the Rove.me website required careful evaluation. Our decision wasn’t just about technical capabilities — it was about aligning the framework with the unique demands of the project and ensuring a sustainable development process. As for our goals after the transition, we aimed at:
- Updating technologies without sacrificing functionality for our users or harming SEO
- Improving tech metrics (load speed, stability, SEO)
- Optimizing the development process
To make the right decision, we considered the following factors:
SSR and static generation. Since Rove.me is a content-driven platform, SSR and static site generation were non-negotiable requirements. A new framework had to ensure these capabilities for maintaining fast page load times, improving SEO performance, and delivering a better user experience.
Multi-language support. Supporting six languages across both the interface and content required robust internationalization features. We needed a framework that could simplify the handling of translations and localization without relying on large, manually maintained JSON files.
Ease of onboarding and collaboration. The Rove.me project often involved contributions from developers who worked temporarily on the codebase. This is why it was critical to choose a framework that was widely adopted within our team, ensuring a low learning curve and simplifying collaboration.
After considering several options, such as RedwoodJS, Gatsby, Remix and others, Next.js stood out as the most fitting framework for our needs.
Next.js natively supports server-side rendering and static site generation, which aligns perfectly with our SEO and performance goals. The framework’s built-in support for multi-language setups allows for simplifying the management translations and localization. Also, for our team that is already well-versed in React, choosing a React-based framework would ensure smooth collaboration. In addition, Next.js is widely adopted, which means that we can easily find resources, examples, and solutions when needed.
Main challenges during the transition to Next.js
Did Next.js seem like a perfect fit for our project? Yes. Did we transition as easily as we expected and live happily ever after? Well, there wouldn’t be a story without a bit of a challenge.
Starting with Next.js 13, the framework introduced the App Router, intended to replace the Pages Router as the primary approach for implementing website interfaces. The App Router optimizes server-side rendering and allows using advanced capabilities such as React Server Components (RSC).
This technology opened up opportunities for us to use great features like HTML streaming and prefetch, both of which would boost website performance. I was excited to implement upgrades for our platform using the App Router, as it promised faster load times and better SEO metrics. Here’s how it turned out to be in practice.
Challenge #1: Handling multilingual content
Since our website needs to support six languages, it requires incorporating locales in our code. Unfortunately, there was no straightforward way to use locales in the App Router configuration system.
To address this issue, I used a middleware file that helped to determine the appropriate language before serving the content.
Challenge #2: Difficulties with HTML streaming and prefetch
HTML streaming is a feature that sends parts of the page to the browser as soon as they are ready, allowing users to see content faster. We wanted to implement streaming to increase the load speed of the Rove.me website but faced another obstacle. As I have already mentioned in the beginning, our codebase was written in Javascript which can often be disabled in search bots. This meant that the layout of a webpage looked differently for the bots and critical SEO elements could potentially go unindexed, negatively impacting our metrics. Below you may see the illustration of this issue.
After disabling streaming, we encountered significant delays during page transitions. To try and overcome this problem, we explored prefetch — a feature that preloads resources for pages linked on the current page, speeding up navigation for users. And even though prefetch is a useful feature, it also posed risks to SEO. Search bots with JavaScript enabled might detect preloaded resources as standalone pages, leading to unnecessary indexing or duplicated content.
Therefore, for the time being, we disabled streaming and prefetch features, prioritizing SEO performance while planning for future refinements to safely reintroduce them.
Challenge #3: Styling conflicts and duplication
After shifting to Next.js, we noticed that it occasionally duplicated CSS rules across different components. This issue led to styling conflicts and disrupted UI elements. For example, even minor adjustments to shared elements like buttons could create cascading issues, as shown below. The orange button was supposed to have text on it, however in reality it looked like this:
To deal with this issue, I had to adopt stricter CSS management practices and increase style specificity where necessary.
Our achievements
As you can see, the journey to a new Rove.me website was quite bumpy but we coped with our challenges. So, was it worth the trouble? Let’s talk about the key benefits that transitioning to Next.js brought us.
Tech enhancements
After the shift, the Rove.me platform saw faster page load speeds, fewer errors in the Google Search Console, and overall performance improvements on both desktop and mobile.
2023
2024
Simplified multi-language support
Integrated workflows for exporting and synchronizing translations with external platforms replaced the huge and inconvenient JSON files, where the translations were previously stored.
Streamlined development
Next.js allowed us to work on the frontend without launching the entire stack, saving time and effort. Choosing the framework and infrastructure that is familiar to the entire team improved the team collaboration on the project and simplified the onboarding of new team members. In addition, clear architecture and efficient tools incorporated into the framework provided an all-in-one solution, which reduced reliance on custom or external software. As a result, the tasks that used to take days of developer time can now be completed in minutes.
All in all, transitioning to Next.js was a journey filled with obstacles, learning, and growth. It helped us optimize the Rove.me platform, improve our workflows, and deliver a better experience for our users.
If you found this article insightful, stay tuned! We’ll continue sharing our experiences, challenges, and best practices as we keep working on software that achieves great results.