Pre-rendering (SSG)
What is pre-rendering?
Pre-rendering means to render the HTML of pages at build-time (when running $ vike 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 makes deployment very easy and very cheap (mostly free). It's also significantly more performant as the HTML isn't re-generated on every HTTP request.
But pre-rendering cannot be used for websites with content that changes very frequently. For example Hacker News or Reddit: new content is created every time a user posts something new. Pre-rendering cannot be run again every (milli)second whenever there is new content (Reddit has millions of pages that cannot be re-rendered every (milli)second).
In theory, it's possible to re-render only the subset of pages that are affected by new content, but it isn't practical (it has been tried before) and we recommend against this practice.
Technically speaking, what matters is how frequent the HTML of pages changes, see also:
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 GitHub Pages, a static host which is completely free, easy to use, and very performant.
How to pre-render
To opt into pre-rendering:
// pages/+config.ts
import type { Config } from 'vike/types'
export default {
prerender: true
} satisfies Config
List of options: API > +prerender
.
Your pages' HTML will be rendered when you run $ vike 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 Vike's CLI instead of a server ($ vike dev
and $ vike preview
). See linked examples below.
You can programmatically invoke the pre-rendering process, see API > JavaScript 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 Vike 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 Vike CLI usage)
SSG vs SSR
The only difference between SSG and SSR is when the HTML is rendered:
- SSG: the HTML of the page is rendered at build-time (when calling
$ vike build
). - SSR: the HTML of the page is rendered at request-time (when the user goes to the page).
The client-side code of pages is loaded and executed in the user's browser and, therefore, always runs at request-time.
If you pre-render all your pages, then there isn't any server-side code, because all the "server code" runs at build-time.
With pre-rendering it's a misnomer but we still call it "server-side code" to keep the docs simple. One way to think about it is that pre-rendering means "pre-rendered server-side code".
Essentially, and technically, SSG means SSR + pre-rendering:
// pages/+config.ts
import { Config } from 'vike/types'
// SSG
export default {
prerender: true,
ssr: true // (optional: `ssr` is true by default)
} satisfies Config
See also:
SPA
SPA means the page is rendered only on the client-side.
See also: What is SSR and SPA?
In other words, no SSR:
// pages/+config.ts
import { Config } from 'vike/types'
// SPA
export default {
ssr: false
} satisfies Config
But when the user visits an SPA page, the browser still needs an HTML response to kick off client-side rendering. This HTML is just an empty shell (it doesn't contain the content of the page). If you want to avoid the need for a production server, you can pre-render this empty shell:
// pages/+config.ts
import { Config } from 'vike/types'
// SPA
export default {
prerender: true,
ssr: false
} satisfies Config
That's why it's a common practice to set ssr: false
together with prerender: true
.
You can also add meta page information (title, description, social image, ...) to the pre-rendered HTML of SPA pages, see Guides >
<head>
tags.
Can I use SSG + SPA?
Yes, you can have some pages be SSG while other pages are SPA.
Technically, you still pre-render all your pages, it's just that the content of some pages are rendered to HTML (SSG) while the content of others pages aren't rendered to HTML (SPA).
See explanation in the SPA section above.
For example:
pages/+config.js
pages/(marketing)/+config.js
pages/(marketing)/index/+Page.js # SSR
pages/(marketing)/about/+Page.js # SSR
pages/admin-panel/+config.js
pages/admin-panel/index/+Page.js # SPA
// pages/+config.ts
import { Config } from 'vike/types'
export default {
// Pre-render *all* pages
prerender: true
} satisfies Config
// pages/admin-panel/about/+Page.js
import { Config } from 'vike/types'
export default {
// SPA
ssr: false
} satisfies Config
// pages/(marketing)/about/+Page.js
import { Config } from 'vike/types'
export default {
// SSG
ssr: true // (optional: `ssr` is true by default)
} satisfies Config
See also:
See also
Pre-rendering options: