Static Site Generation (SSG) Overview

Static Site Generation, or commonly referred to as "SSG", is the process of pre-rendering site webpages into static HTML files. The benefit is that when a visitor requests the webpage, the response is a pre-generated HTML file (a static file), and doesn't require the webpage's HTML to "rebuild" on the visitor's browser, or dynamically created by your server (more on this later).

Additionally, due to Qwik's underlying architecture, page performance also benefits by not requiring a Javascript "hydration" step, which can significantly lower performance and slow down user interactivity. By pre-rendering static index.html files with SSG, and combined with Qwik's resumability, static site generation offers many performance benefits over legacy solutions.

SSG vs. Server-Side Rendered (SSR)

Qwik City is capable of taking a Qwik application, no matter if it's a "webapp" or "website", and generate static HTML. Once it's generated as HTML, Qwik is fundamentally able to skip rebuilding the app by using resumability, since the app was already generated as HTML. Both Static Site Generation (SSG) and Server-Side Rendering (SSR) use the same process to generate the HTML. The main difference between the SSG and SSR however, is "when" the HTML is generated.

In a traditional setup, SSG pre-renders each webpage at build-time, while SSR render's each webpage on-demand for each HTTP request. SSG only needs to generate the HTML one time per build, which is great for webpages where each visitor should see the same content. In contrast, SSR is great when the webpage may be different for each visitor, and would need to render custom HTML for each individual HTTP request.

For example, SSG is ideal for a blog or docs site, where all the content should be the same for each visitor. While SSR may work fine for a blog, it may be an unnecessary strain for your HTTP servers to render the blog content for every visitor, even though they'd all end up seeing the same HTML.

However, an account dashboard would commonly have different content for each signed-in user. In this setup, each user should get their own rendered HTML with their account information, rather than everyone seeing the exact same content. This is where SSR would be preferred.

Ideally, the more you can do with static site generation the better, since that'll have less costs to your servers and faster response times.

With Qwik City however, the decision to use SSG or SSR, does not have to be one or the other decision. Instead, your own implementation can choose to have some route paths use SSG, while some other pages use SSR. It's entirely up to you and your requirements.

Static Site Generation Config

Static site generation is created from the built in adapter, to create an adapter run:

npm run qwik add

Select Adapter: Static site (.html files). Done!

Changes

Running the above command will make the following changes to your project:

  • A build.server script will be automatically added to your package.json file.
  • A adapters/static/vite.config.ts file will be created.

In node you can run the generation after building using:

node server/entry.ssr.js

Your build files will be generated into the dist folder.

SSG Config

The adapters/static/vite.config.ts file also includes the SSG config, which would be custom for each implementation.

origin

The URL origin, which is a combination of the scheme (protocol) and hostname (domain). For example, https://qwik.builder.io has the protocol https:// and domain qwik.builder.io. However, the origin does not include a pathname.

The origin is used to provide a full URL during Static Site Generation (SSG), and to simulate a complete URL rather than just the pathname. For example, in order to render a correct canonical tag URL or URLs within the sitemap.xml, the origin must be provided too.

If the site also starts with a pathname other than /, please use the basePathname option in the Qwik City config options.

outDir

The outDir is a file system output directory where the static files should be written. In the example above, it's using Node's fileURLToPath to create an absolute file system path to write the static HTML files to.

Javascript Runtimes

For a Javascript project, it's quite common for the build's runtime to be built on top of Node.js. However, the core of Qwik City static site generation isn't tied to using only Node.js, which is why the qwikCityGenerate() function is imported from @builder.io/qwik-city/static/node. By scoping the generate function to a specific runtime, such as Node.js, this gives Qwik City the flexibility to also generate SSG from other runtimes in the future, such as Deno or Bun.

Dynamic SSG Routes

import { component$ } from '@builder.io/qwik';
import { useLocation } from '@builder.io/qwik-city';
import type { StaticGenerateHandler } from '@builder.io/qwik-city';

export default component$(() => {
  const { params } = useLocation();

  return <div>Example: {params.id}</div>;
});

export const onStaticGenerate: StaticGenerateHandler = () => {
  const ids = [...]; // id data load implementation

  return {
    params: ids.map((id) => {
      return { id };
    }),
  };
};
Made with โค๏ธ by