Full Static Generation with NuxtJS v2.13

Jul 21, 2020

Some information in this article may be out of date. For NuxtJS v2.14 check this article.

Introduction

With the nuxt generate feature we have already been able to create static sites. This feature was mainly working with pre-rendering pages. When we navigate pages client-side asyncData and fetch hooks are called, making a request to our API. But since the next page has already been pre-rendered we don’t need these hooks to be called every navigation. Instead, we can create a payload file that contains pre-rendered DOM content to mock asyncData and fetch on client-side navigation. The new nuxt export feature does this and this way it can create fully static web pages.

Configuration

New Property

We have a new target property for telling Nuxt that we want to export our application for static hosting. In nuxt.config.js we can set this property to static for static hosting or to server for server-side rendering.

export default {
  target: 'static' // default: 'server'
}

New Commands

For target: 'static' there are new commands we can use: nuxt export and nuxt serve.

nuxt export (deprecated in v2.14)

nuxt export command generates every route as an HTML file in /dist directory.

It should also be noted that nuxt export does not call nuxt build by default differently than nuxt generate. So when using nuxt export the project should already be built by nuxt build. By this separation, if there are only content changes, we can only re-render our pages. No Webpack build -> faster redeploys. 😎

nuxt serve (deprecated in v2.14)

Once we statically generate our Nuxt app into dist/, we can use nuxt serve to start a production HTTP server and serve our static app with supporting SPA Fallback.

SPA Fallback is basically having a single page application inside our static site. For example, we may want to prevent pre-render of pages like /admin or /login. With SPA Fallback these pages will still be accessible with client-side rendering.

Smart Prefetching

Since v2.4, Nuxt was able to automatically prefetch code-splitted pages linked with <nuxt-link> when visible in the viewport. With v2.13, this feature can also prefetch the payloads created with nuxt export.

Although instant navigation could improve the user experience, it may be useful to disable this feature in content listing pages, such as all articles page, to prevent excessive server requests.

To disable the prefetching on a specific link, we can use the no-prefetch prop.

<nuxt-link to="/about" no-prefetch>About page not pre-fetched</nuxt-link>

Also, we can disable prefetching on all links by setting router.prefetchLinks: false in nuxt.config.js.

export default {
  router: {
    prefetchLinks: false // default: 'true'
  }
}

And use prefetch prop to enable prefetching on a specific link.

<nuxt-link to="/about" prefetch>About page pre-fetched</nuxt-link>

Integrated Crawler

We also have an integrated crawler, detecting every relative link in pages and adding to routes. If we want to exclude a bunch of routes, we can use the generate.exclude. We can keep using generate.routes to add extra routes that the crawler could not detect.

export default {
  generate: {
    exclude: ['/my-secret-page'],
    routes: ['/dynamic-link-which-is-not-referenced-in-any-page']
  }
}

The export property added in nuxt.config.js which is currently an alias of generate, will take over for Nuxt 3 removed in v2.14. 😜

If you have too many dynamic pages you can disable the crawler by setting generate.crawler: false and add dynamic routes on your own for performance reasons.

export default {
  generate: {
    crawler: false // default: 'true'
    routes: async () => {
      // return routes array
    }  
  }
}

Hooks

There are also export hooks that are slightly different than generate hooks. export hooks removed in v2.14. You can continue using generate hooks.