Pre-rendering (SSG)

What is pre-rendering?

Pre-rendering means to render the HTML of all our pages at build-time.

Normally, the HTML of a page is rendered at request-time (when the user navigates to that page) but, if we using pre-rendering, the HTML of the page is rendered at build-time instead.

When using pre-rendering, we don't need a Node.js server: our app consists only of static assets (HTML, JS, CSS, images, ...) and we can deploy these static assets to a so-called "static host" such as GitHub Pages, Cloudflare Pages, or Netlify.

If we don't use pre-rendering, then we need a Node.js production server (or a Node.js-like environement such as Cloudflare Workers or Vercel) in order to be able to dynamically render our pages' HTML at request-time.

Tools that pre-render pages are commonly called Static-Site Generators (SSG).

How to pre-render

To pre-render our pages, we use the CLI command $ vite-plugin-ssr prerender after having run $ vite build.

  • npm: $ npx vite build && npx vite build --ssr && npx vite-plugin-ssr prerender.
  • Yarn: $ yarn vite build && yarn vite build --ssr && yarn vite-plugin-ssr prerender.

The generated static assets are then available at dist/client/.

For a page with a parameterized route (e.g. /movie/:movieId), we have to use the prerender() hook in order to provide the list of URLs that are to be pre-rendered.

We can also use the prerender() hook to accelerate the pre-rendering build step.

React Example:

Vue Example:

Partial pre-rendering

By default the command $ vite-plugin-ssr prerender pre-renders all our pages. To pre-render only some pages, we can use the partial option and .page.server.js#doNotPrerender

SSG vs SSR

The only difference between using $ vite-plugin-ssr prerender (SSG) and using renderPage() (SSR) is when the HTML of pages are rendered:

  • SSG: our pages' HTML are rendered at build-time (when we call the $ vite-plugin-ssr prerender command)
  • SSR: our pages' HTML are rendered at request-time (when the user goes to our website and renderPage() is called)

Client-side code is loaded & executed in the user's browser and is therefore always executed at request-time.

Should I pre-render?

We should use pre-rendering whenever we can. Because pre-rendering removes the need for a Node.js server which makes deployment an order of magnitude easier. It's also more performant as HTML isn't re-generated on every request.

The problem is that pre-rendering cannot be used for every kind of website. So the question of whether to use pre-rendering boils down to: can I use pre-rendering?

Pre-rendering cannot be used for websites that have highly dynamic content. For example, a social site such as Hacker News or Reddit has highly dynamic content: the content changes every time a user posts a new link or writes a new comment. We cannot use pre-rendering because with pre-rendering the HTML is stuck at build-time and we cannot re-build the entire website every time there is new content.

Pre-rendering works for websites with content that changes only occasionally, such as a few times a day. For example, https://vite-plugin-ssr.com is updated only occasionally, and the entire https://vite-plugin-ssr.com website can be re-build every time the vite-plugin-ssr maintainers change its content. Pre-rendering enables the deployment of https://vite-plugin-ssr.com to GitHub Pages which is an order of magnitude easier (and more performant) than using a Node.js production server.