Performance

A guide to Incremental Static (Re)generation (ISG and ISR) With Layer0 and Nuxt.js!

Yeah, you saw that right, it’s Nuxt.js and not Next.js! To enable Incremental Static (Re)Generation with Nuxt.js, projects can now be deployed at Layer0 (formerly Moovweb) to get the beyond JAMSTACK experience alike Next.js and Gatsby. In this blog, I want to explore what is Incremental Static (Re)Generation (ISG and ISR), the benefits, the drawbacks, how ISG and ISR can be implemented across frameworks, especially with Nuxt.js and Layer0, and finally enlist an awesome example to get you started on the same.

What is Incremental Static (Re)Generation?

Introduced by developers of Next.js, ISR is “updating static content after you have already built your site”. One can understand Incremental Static (Re)Generation, in two parts: Incremental Static Generation and Regeneration of web pages.

For understanding Incremental Static Generation, let the explanation be guided by a scenario where a page requested by the user was not pre-rendered while statically exporting the website. In such a case, a fallback page is served while the data loads. Further, upon completion of building the page with the fetched data, the page is then cached onto the server. Any user requesting the page then would skip over the fallback and loading stages, and directly see the built page. Superb!

Regeneration is inspired by the concept of stale-while-revalidate, where stale data is refreshed at regular intervals of ‘revalidate’ seconds. For pages that have staleWhileRevalidateSeconds value configured, they would be re-built after regular intervals of the configured value.

[Incremental Static (Re)Generation as per Layer0 docs]

This can be followed up by two questions:

  1. Does that allow the pre-rendered pages to be regenerated during runtime? Yes, the pre-rendered pages when deployed would also be ‘revalidated’ after intervals of staleWhileRevalidateSeconds seconds.
  2. Can new dynamic pages be generated during runtime without using SSR? While there can be client side rendering for the pages that are being built at runtime (i.e. serving the fallback), avoiding SSR altogether for ISG seems unfeasible.

The benefits of ISG and ISR

With Incremental Static Generation and Regeneration, creates the possibility to initially have the minimal static export, and then create and regenerate the pages on-demand, without re-building the website. This would account to faster deployments, hassle-free handling of regenerating the pages without the need to re-build the website.

The drawbacks of ISG and ISR

As the concept is inspired by stale-while-revalidate, the data is certain to be stale for a period. This nature might be undesired for a web product that aims to serve fresh content for each user. Using ISG or ISR would lead to serving the content that is yet to be updated for some set of the users (those who hit it before revalidation time), or might show the fallback for some (those who hit it after maxAgeSeconds time). This might lead to degraded user experience, but that is very specific to the use case.

Incremental Static (Re)Generation with Nuxt.js and Layer0

To configure Nuxt.js apps to have IS(R)G follow the steps below:

Getting started: Create a nuxt app by the following command:


npm create nuxt-app project-name

For Choose custom server framework select None

  • For Choose rendering mode select Universal (SSR)

In case you already have a nuxt app, just maintain the above configurations and would be good to go.

0. Add the Layer0 CLI via:


npm i -g @layer0/cli

1. In nuxt.config.js, add "@layer0/nuxt/module" to buildModules:


module.exports = {  buildModules: [['@layer0/nuxt/module', { layer0SourceMaps: true       }]],}

2. Run


layer0 init

3. For IS(R)G, use routes.js (Created automatically by layer0 init command) and add route for the dynamic pages `/some-route/_slug.vue` as following:


// This file was added by layer0 init.
// You should commit this file to source control.

const { Router } = require("@layer0/core/router");
const { nuxtRoutes } = require("@layer0/nuxt");

module.exports = new Router()
  .match("/service-worker.js", ({ serviceWorker }) => {
    serviceWorker(".nuxt/dist/client/service-worker.js");
  })
  .get("/some-route/:slug", ({ cache }) => {
    cache({
      edge: {
        maxAgeSeconds: 60 * 60 * 24, // keep the incrementally generated page for a day
        staleWhileRevalidateSeconds: 60 * 60 // revalidate the data on page every hour
      }
    });<
  })
  .use(nuxtRoutes);

4. To test locally how the app would do in production, run the following:


layer0 build && layer0 run --production

5. To deploy run:


layer0 deploy

6. Celebrate! 🎉


Enabling ISG via Layer0 with other frameworks

With Layer0’s magical goodies on the top, after running layer0 init, Incremental Static Generation can be enabled with any framework by just adding the following to routes.js (below, the on-demand dynamic page is being served at `/item/:id`):


router.get('/item/:id', ({ serveStatic, cache, renderWithApp }) => {
cache({
edge: {
maxAgeSeconds: 60 * 60 * 24, // cache at the edge for 24 hours
},
})
serveStatic('dist/item/:id.html', {
// In case a user requests a page that is not already statically rendered, fall back to SSR.
onNotFound: () => renderWithApp(),
// While SSR is in progress, display a static loading page.
loadingPage: item/loading.html',
})
})

Example Of Incremental Static Regeneration with Layer0:

With Layer0, it’s easier than ever to implement Incremental Static Regeneration for different purposes with different frameworks. The following seeks to implement ISR with Nuxt.js via Layer0.

GitHub: https://github.com/rishi-raj-jain/static-medium-isr-in-nuxtjs-with-layer0

Website: Static Medium


Techniques that are being implemented in the example above:


Want to take your site to the next level?
Join the Layer0 Newsletter for the latest updates on performance.
Thank you! You've been added.
Oops! Something went wrong.
Thanks for registering, you're being redirected!
Oops! Something went wrong.

Don't wait another second. Go instant.

Get started in seconds