One advantage of React is the clean modularity of its components. While most React sites are dynamic single-page applications, the modularity React offers means that it is also used in static sites.
The first big static site generator that used React was Gatsby, but now the new cool kid on the block is Next.js. How does it fare?
There are many advantages to static sites but also downsides.
A significant disadvantage about static websites is that static sites commonly suffer from a problem of not giving editors a quick feedback loop on what the final website will look like.
One of the great features introduced by Gatsby was the preview system, so you could update the CMS and instantly see the results on a mirrored website that is available only to editors.
Next.js also has a preview system, but instead of having another website, you can see the changes directly on the production website (without real users being able to snitch on the unpublished changes).
We will look at the pros and cons of these two systems.
When to use Gatsby or Next.js
Working with Javascript is always a race against time: we don’t know if some library will be maintained for long enough or if something new and more performant will come out in a couple of weeks.
At Leanpanda we had to deal with this problem when it came to choosing a Static Site Generator (“SSG”) to pair with DatoCMS, and initially, we chose Gatsby for sites that needed a rich frontend.
Anyway, comparing these two SSGs doesn’t make much sense if we don’t consider different use cases.
First of all, we will be looking at them from a developer’s perspective, analysing how to code them and what advantages we get from developing a website using one or the other.
Secondly, we will track the pros and cons from an editorial point of view, so we will keep in consideration behaviours like having a preview, how to handle data, and so on.
Last but not least, we will look at the end-user, the customer experience.
Let’s start with GatsbyJS.
Gatsby can be fun, easy, and quick to get something working right away, but:
- It is a pain to develop;
- It is only static!
How Gatsby JS works
So this is how we use Gatsby:
We fetch data through GraphQL that we need to generate pages.
This happens in the gatsby-node.js file, where we iterate over the locales array and, for each locale, we generate pages in different languages.
What we call pages here might be confusing. In Gatsby there are two folders, pages and templates.
The pages are the ones that will stay as you code them, so if we have a page called about.js that page will show exactly what you have written inside and you can find the page at the route `/about`.
The templates are the files that you specify when you create pages, so if you fetch data from your CMS and want to create, for example, the /team/elon-musk page you will have a template called team-member.js that you pass in the create function at the time of build. The newly created page will have the styles of the template.
Inside the template we fetch all the page content, from the title to the galleries to the SEO tags.
From within the page we call the CMS and get the data we want, using GraphQL, through props.
The Pros and Cons of Gatsby
After a few months of working with Gatsby though, we found ourselves fighting incomprehensible errors, the cache wasn't cleaning properly, and, most importantly, after having a lot of records passing through GraphQL the build time went from a few seconds to many minutes!
This last part isn't GatsbyJS's fault directly, the problem here is GraphQL, which unfortunately is the only way to fetch data that Gatsby allows us to use.
Now we have seen how Gatsby works, we can recap the pros and cons based on the three fields of interest.
From a dev point of view
Pros:
- Easy to setup;
- Performant;
- Best choice for small, simple websites.
Cons:
- Pure SSG, doesn’t (natively) allow dynamic pages;
- Invalidating the cache is a pain.
As an editor
Pros:
- Easy to change data as you will be working on the CMS itself;
- You can use any CMS that will support GraphQL, we use and recommend DatoCMS which is fast easy to use, and always updated with cutting edge technology.
Cons:
- There is not a *proper* preview mode, there is one which is a hack based on React’s dev mode and it costs money to use it;
- Having a lot of data will slow build time down a lot. We had a website that used ~1000 records (pages and single instances) and it took 8 minutes to build.
As a user
Pros:
- Very fast websites.
Cons:
- As a static website is hard to have cons, and they will not be related to Gatsby.
How Next.js works
Our new go-to solution is called Next.js which, first of all, allows us to decide how we are going to fetch the data. In fact, you just have a getInitialProps() function that will let you use a `fetch()` to get data from an API the way you want.
Fetching the data from this function will allow us to send content to the pages via props, just like Gatsby.
getInitialProps can only be added to the default component exported by a page, adding it to any other component won't work.
The value here is that rather than having to use GraphQL every time, Next.js leaves the decision of how you want to handle data to the developer. If you find a bottleneck using GraphQL, just switch to something else.
Another great feature that Next.js offers is that we can have both static and dynamic pages. Rather than having all static pages like Gatsby does, we can decide to have SSR pages that will be handled just like any other server-side language.
The Pros and Cons of Next.js
As a developer
Pros:
- Very versatile as it lets you choose how to fetch your data;
- Makes both static and dynamic pages happily live together;
- getStaticProps and getServerSideProps are very helpful in handling how you fetch data.
Cons:
- Harder than GatsbyJS, it takes more time to code and a higher skill level;
- Server-side knowledge required (if you want to have SSR pages);
- You are obliged to use Vercel to handle the deployment and build configuration.
As an editor
Pros:
- Fetch data the way you want, you can use any CMS (or other custom systems) that you prefer as long as they expose an API;
- Real time cookie-based content editing, no need to set another environment, you enter data on the CMS and you can instantly see how it looks on the website before publishing it.
Cons:
- Nothing in particular.
As a user
Pros:
- The website could be half static and half dynamic, so the variety of customers will change and you can meet pretty much every need.
Cons:
- The dynamic part of the website could possibly break (although it is rarer than fully-dynamic sites).
A fair comparison
To be clear, this is not a deathmatch between two site generators, it is more a comparison to understand which one will work better for the job you have to do.
From a developer’s point of view, it is harder to work with Next.js but (paradoxically) it ends up being less painful.
For an editor, Next.js is better as a preview mode is available where the real data will be displayed just as it will look in production.
Let's make an example
Let’s assume we have a big blog with >100 pages.
Static approach
If we make all static pages we’ll have to wait for Gatsby to render them all. After the build is completed we can view the website (it will be fast from the first visit, but it takes ages to build).
Dynamic approach
Now let’s make the last 10 posts static and, thanks to Next.js, we will let the server handle the rest.
The website will take less than a minute to build because of the few static pages, so the website will be visible earlier.
Once someone wants to visit the old posts, the server will render that page, so the visitor would wait like a normal dynamic website, but only the first time. The second visitor will get the page already staticized.
Conclusion
Both systems have their pros and cons.
Gatsby is quick to get started and produces unbreakable static web sites. It has a preview system (that comes with a cost, though) and it is pretty straightforward. Anyway, on the other hand, don’t expect to be blazingly fast at build time, because it can take tons of time to build if you have > 1000 records on your CMS.
Next.js has a great (and free) preview system and allows you to introduce dynamic elements when and where they are needed.
You are also completely free to fetch the data the way you want.
Next.js is harder to code though. Either if you want to make it mixed (static and dynamic) or only static, it requires more programming knowledge.