Nuxt 3 gives you plenty of options when it comes to rendering your app. There’s static rendering, server side rendering, client side rendering, universal rendering, and incremental generation with swr caching.
Sometimes all the options can be overwhelming. Let me briefly break down each one and then show you a super cool trick to implement multiple rendering modes in a single app!
If your only here for the hybrid rendering, you can jump to the Hybrid Rendering section at the end of this article.
Icons in this image and all below images are by Font Awesome
Client side rendering is where the application is rendered purely in the browser. The server sends back only a minimal amount of HTML just to give the Vue app something to mount to. The HTML served from the browser contains NO content.
This is how a typical Vue application without Nuxt works (that is an app built with Vue CLI or Vite with npm init vue@3
. Often times apps built with this approach are called a Single Page Application or SPA for short. This designation comes from the fact that the nearly empty HTML file is served for all routes and all navigation is done on the client side.
This is accomplished in Nuxt with the the following option in nuxt.config.ts
ssr: false
Most of the Nuxt apps that you see in the wild are server-side rendered. That means the HTML for the Vue application is rendered on the server and then the full page HTML is delivered (content and all) to the browser.
That’s one of the big advantages of using Nuxt over a regular client side Vue.js app. However, most of these apps are also hydrated on the client side. We’ll talk about that more in just a moment (see Universal Rendering).
In Nuxt 3, as of winter 2022, it is possible to only render pages on the server with an experimental module from Nuxt core team member Daniel Roe. The module is called nuxt-zero-js. It “removes all client-side JS from your Nuxt 3 app”.
Usually when you hear about SSR and Nuxt, usually what’s really being talked about is Universal Rendering. The purely SSR approach mentioned above is far from mainstream (understandably as the package that supports it is experimental).
Universal rendering is a mix of both SSR and SPA. Universal apps are first rendered on the server and then “hydrated” on the client. Hydration is the process of injecting the client-side Vue.js application into the existing server rendered HTML.
This is the default rendering mode for Nuxt.
Static site generation is like a universal app in that the full HTML is delivered from the server and then hydrated on the client side. Where it differs is WHEN the HTML is generated on the server. With universal rendering it’s generated at request time. With static rendering (aka Static Site Generation or SSG) it’s generated during a build step.
This build step typically happens on a push to a remote github repo and triggers all pages of the site to be re-generated. Then the static HTML files are served at request time.
This approach was made popular by Netlify. It’s the backbone of the so called “Jamstack”.
You can generate a static site in Nuxt 3 with npx nuxi generate
or in Nuxt 2 with npm run generate
.
Just like Universal rendering mixes SSR and SPA in terms of WHERE the app is rendered, incremental static generation (ISG) is a mix of SSG and SSR in terms of WHEN the app is rendered. In my opinion, it’s basically a glorified cache.
The caching strategy used by ISG is known as SWR or “stale-while-revalidate”. The flow looks like this:
This approach avoids some of the hurdles you face with SSG while still giving you the same great performance.
Now that you know about all the other rendering modes, understanding Hybrid rendering is pretty simple. Hybrid rendering is the ability to mix and match the above approaches within a single app based on route. That means you might have:
/admin
route./blog
route.This is possible since Nuxt RC 12. You can configure it with the routeRules
option in nuxt.config.ts
. Here is an example taken from the Nuxt 3 docs (modified to remove options not related to rendering mode).
export default defineNuxtConfig({
routeRules: {
// Static page generated on-demand, revalidates in background (ISG)
'/blog/**': { swr: true },
// Static page generated on-demand once (SSG - or at least mighty close)
'/articles/**': { static: true },
// Render these routes on the client (SPA)
'/admin/**': { ssr: false },
}
})
I got to play around with this first hand recently for our Nuxt.js 3 Fundamental course and honestly it was just so exciting to me I’ve got to share the video with you. View this lesson for free from the premium course and get a first hand look at hybrid rendering in action.
All the options for rendering your Nuxt app can be confusing but rest assured there is one that’s fit for your use case. Plus, with hybrid rendering you can even tailor a single site by route to get just the right result.
If you’d like to learn more about the fundamentals of Nuxt.js 3 then checkout our course Nuxt.js 3 Fundamentals.
If you’d like to learn Nuxt 3 in the context of a real world application, then checkout the course Mastering Nuxt 3. In it, avid Vue content creator Michael Thiessen will take you step by step through the build of a video course application.
Our goal is to be the number one source of Vue.js knowledge for all skill levels. We offer the knowledge of our industry leaders through awesome video courses for a ridiculously low price.
More than 200.000 users have already joined us. You are welcome too!
© All rights reserved. Made with ❤️ by BitterBrains, Inc.