Demystify Nuxtʼs target, mode, and ssr properties

There are two JavaScript front-end frameworks that rule the world these days. Personally, I believe React and Vue are the unofficial winners in the “Capture The Developerʼs Attention” game. Over time, these two projects helped to evolve a whole new framework ecosystem with out-of-the-box support for static sites, server-side rendering, and many other perks without tedious configuration. According to staticgen, Nuxt.js is one of the most popular frameworks and is still growing. I believe itʼs mainly because of its great documentation where you can always quickly find what youʼre looking for. The only thing I found hard to understand and I was struggling with were all the possible config combinations for various targets, modes, and their respective commands.

Nuxt provides you with several ways to run your application. You can have a classic single page application, super-fast static site, or even a server-side rendered app. In the beginning, it might be a good idea to briefly distinguish among them.

  • Single Page Application (SPA) - This is similar to the classic Vue app. The HTML is still rendered with pure JavaScript on the client-side. This is a good first transition step from Vue to Nuxt.js benefiting from the Nuxt configuration and framework.
  • Server Side Rendered (SSR) - This one is also called universal or isomorphic. The main difference is in the rendering, which happens purely on the Node.js server. Its biggest advantage, when compared to the SPA, is far better SEO support.
  • Static Site - Trendy (Jamstack), fast, cheap, secure, and performing. All HTML pages are pre-rendered at the build time and are served from CDN. Of course, itʼs not a silver bullet for all use cases and is not suitable for some projects.

After the initial research when you clarify which rendering is the right choice for your project, itʼs time to configure nuxt.config.js —the main config file for your Nuxt.js app. There are three main config properties that specify the behavior of your app: targetmode, and ssr.

Target

Youʼve got two options for the target property: server or static. It might be helpful to think about the target property as a hosting environment—whether you need: 

  • a server, or
  • just a CDN to serve static files.

target: 'server'

Despite the fact itʼs called target: 'server' and the old documentation said thatʼs for server-side rendering, it doesnʼt literally mean your app is server-side rendered. This was really obfuscating for me. For this purpose, Nuxt.js has additional mode or ssr properties, but weʼll get to that.

When using the target: 'server', your production app will need a server environment where the response for the clientʼs request is composed and is sent.

target: 'static'

On the other hand, when using the target: 'static' in a production environment, you just need a CDN that will serve your static files. These static files are prepared at the build time and are final (until the next build with updated content or code). There is no need for any server in this scenario (other than CDN and build server, which will probably be in your CI pipeline).

This option is available from version 2.14.0. Before this release, the old approach had had some issues and difficulties, mainly with the client requesting your API via asyncData and fetch functions for your navigation. As a result, the generated site was not purely static whatsoever. All the drawbacks of the old approach are described in the official documentation.

With the new target: 'static' (and mandatory ssr: 'true' at the same time) approach, the nuxt generate command will pre-render all your HTML pages and mocks async data requests. That old asyncData and fetch are not requesting your API from the client this time. This was already being performed during the build time.

Server or static choice?

It might be a little bit tricky for newcomers to decide whether to use server-side rendering or static. A good question that might help you make the decision is: Do you need to provide different content for each page/document/content item for different users/circumstances? If so, you should probably go with the server target, otherwise static.

Each of these approaches has got its pros and cons, such as server requirement, security, speed, CI pipeline/build process, SEO, price, etc.

Mode and ssr

If you are familiar with Nuxt.js, you probably know there are two available values for the mode property - mode: 'universal' and mode: 'spa'.  According to the latest documentation, they were deprecated in favor of ssr: 'true' and ssr: 'false'.

mode: 'universal'

This option was deprecated, you should use the  ssr: 'true' instead.

mode: 'spa'

This option was deprecated, you should use the  ssr: 'false' instead.

ssr: 'true'

With this option, your app is server-side rendered. This is the default value.

ssr: 'false'

With the ssr: 'false' option, there is no server-side rendering (only client-side navigation), and the whole app runs as a single page application. This mode is not available in combination with the target: 'static' option.

TL;DR: Available commands and rendering

Full static works only with target: 'static' and ssr: 'true' (counterpart of deprecated mode: 'universal'). The ssr: 'true' is a default value. The ssr: 'false' is a counterpart of the deprecated mode: 'spa' and cannot be used with target: 'static'.

Also, there are several commands available out of the box by Nuxt.js. Some of them are available with some deployment targets only. Moreover, the table below shows the possible target, mode and ssr combinations with the respective result application.

Originally published at kontent.ai.

Published September 21, 2020

Personal blog
Martin Makarsky on Twitter