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:
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:
- /examples/react-full/vite.config.ts (see setting
prerender
option totrue
) - /examples/react-full/pages/hello/+onBeforePrerenderStart.ts
- /examples/react-full/pages/star-wars/index/+onBeforePrerenderStart.ts
- /examples/react-full/package.json (see Vite CLI usage)
Vue Example:
- /examples/vue-full/vite.config.ts (see setting
prerender
option totrue
) - /examples/vue-full/pages/hello/+onBeforePrerenderStart.ts
- /examples/vue-full/pages/star-wars/index/+onBeforePrerenderStart.ts
- /examples/vue-full/package.json (see Vite CLI usage)
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: