Pre-rendering (SSG)

What is pre-rendering?

Pre-rendering means to render the HTML of pages at build-time (when running $ vite build).

Without pre-rendering, the HTML of a page is rendered at request-time (when the user goes to that page).

If you pre-render all of your pages, then you no longer need a production server: your app will consist only of static assets (HTML, JS, CSS, images, ...) that you can deploy to so-called "static hosts" such as GitHub Pages, Cloudflare Pages, or Netlify.

If you don't pre-render, then you need a production server in order to be able to dynamically render the HTML of your pages at request-time. (A Node.js production server, or a Node.js-like production environment such as Cloudflare Workers or Vercel.)

Tools that pre-render pages are also known as "SSG" (Static-Site Generators).

Should I pre-render?

In a nutshell: pre-render your pages whenever you can.

Because pre-rendering removes the need for a production server and therefore makes deployment easy. It's also significantly more performant as the HTML isn't re-generated on every HTTP request.

But pre-rendering cannot be used for every kind of website.

Pre-rendering cannot be used for websites with content that changes very frequently. For example, a social site such as Hacker News or Reddit: new content is created every time a user shares a link or writes a comment. Pre-rendering cannot be run again and again every other (milli)second whenever there is new content (Reddit has millions of pages which obviously cannot all be re-rendered every other millisecond). (In theory, it's possible to re-render only the subset of pages that are affected by new content, but it isn't practical and we recommend against this practice.)

Pre-rendering can be used for websites with content that changes only occasionally. For example, the content of https://vike.dev changes only when a maintainer updates the documentation: all pages of https://vike.dev can then be pre-rendered again. Thanks to pre-rendering, https://vike.dev is deployed to the static host GitHub Pages, which is a lot easier (and more performant) than using a production server.

How to pre-render

To opt into pre-rendering:

// vite.config.js
 
import vike from 'vike/plugin'
 
export default {
  plugins: [
    vike({ prerender: true })
  ]
}

List of options: API > prerender.

Your pages' HTML will be rendered when you run $ vite build and the generated HTML files are available at dist/client/.

For a page with a parameterized route (e.g. /movie/@movieId), you have to use the onBeforePrerenderStart() hook in order to provide the list of URLs that are to be pre-rendered. The onBeforePrerenderStart() hook can also be used to accelerate the pre-rendering process.

Instead of providing a list of URLs, if you want a parameterized route to be resolved dynamically on the client-side, then see the workaround at #1476 - Pre-rendered dynamic routes (static host deployment).

By default, all pages are pre-rendered. To pre-render only some pages, use the partial option with prerender: false.

If you pre-render all your pages, then you can use Vite's CLI instead of a server ($ vite dev and $ vite preview). See linked examples below.

You can programmatically invoke the pre-rendering process, see API > prerender().

React Example:

Vue Example:

SSG vs SSR

The only difference between SSG and SSR is when the HTML is rendered:

  • SSG: the HTML of pages is rendered at build-time (when calling $ vite build)
  • SSR: the HTML of pages is rendered at request-time (when the user goes to that page)

The client-side code of pages is loaded and executed in the user's browser and is therefore always executed at request-time.

See also

Related docs:

Pre-rendering options: