---
title: How Quilium builds the site
description: Understand how Quilium turns your content and templates into the HTML a visitor sees, so you know what changes when, and what stays in your own hands.
updated: 2026-06-22
---

## What you will understand

Quilium has **one** job at request time: turn content plus a template into the finished HTML a visitor loads. This page is the mental model of that render pipeline, not a procedure. For the step-by-step, see [Quickstart](/en/docs/quickstart).

It also draws a clear line: the CSS and JavaScript your pages reference are **yours**. How you produce them is your own local stack, not something Quilium prescribes. More on that below.

## The render pipeline: content plus template to HTML

Quilium is a **structured SaaS CMS with a server-side templating layer**. Nothing renders in the browser as a framework. A request comes in, Quilium resolves which page it maps to, gathers that page's data, runs the template, and returns finished HTML.

The mental model is a separation of three concerns:

| Concern | What it holds | Who owns it |
|---|---|---|
| **Content** | The typed data, content blocks (`custom: {}`) and collection entries (`data: {}`). | Editors, agents |
| **Structure** | The schema: page-types, content-types, collections, routes, queries. | Developers, agents |
| **Rendering** | The **Liquid** templates that turn data into markup. | Developers, agents |

The point of keeping these apart is that content can change forever without anyone touching a template, and a template can be rewritten without migrating content. Each side evolves on its own clock.

When Quilium renders a page, it does roughly this:

1. **Resolve the route.** The incoming URL is matched to a page (a fixed page, or a detail page driven by a `route` like `/article/{{param}}`).
2. **Run the page-type queries.** A page-type declares **route-aware queries**; Quilium runs them and exposes the results as `page.custom.<key>` arrays for the template to read. This is where a detail page fetches its current item, and a listing fetches its collection.
3. **Render the template.** The page-type's Liquid layout fills the root layout, iterates the page's content blocks, and includes one element template per content-type. Each element reads its own fields from `content.custom`.
4. **Return HTML.** The output is a complete document. The visitor's browser does no data fetching to assemble the page.

<div class="q-ph"><i class="fa-regular fa-image"></i><span><b>Placeholder:</b> render pipeline diagram (request &rarr; resolve route &rarr; run queries &rarr; render template &rarr; HTML). To produce from the fil-rouge demo site.</span></div>

For the why behind each piece, the deeper pages are [Architecture](/en/docs/architecture), [The content model](/en/docs/content-model), [Routing and URLs](/en/docs/routing-and-urls), and [Templating philosophy](/en/docs/templating-philosophy). This page only needs you to hold one idea: **HTML is produced on the server, from data the page-type gathered, by a template you wrote.**

<div class="q-callout q-callout-note"><i class="fa-solid fa-circle-info lead"></i>
  <div><b>No client-side framework.</b> There is no hydration step and no client router. A template renders to HTML server-side; CSS and JavaScript are progressive enhancement layered on top, not the thing that builds the page.</div>
</div>

## Your front-end assets are your own

The HTML Quilium renders references a stylesheet and, often, a script. Quilium **serves** those static files, but it does not build them and does not impose a toolchain. How you produce your CSS and JavaScript is entirely your call:

- a bundler and a utility framework (Tailwind, esbuild, Vite, whatever you like),
- plain hand-written `.css` and `.js` files with no build step at all,
- or a CDN, the way the [Quickstart](/en/docs/quickstart) demo loads Tailwind from a `<script>` so there is **no build to run** on day one.

Quilium's only contract is the rendered HTML and the static files it serves alongside it. Pick the front-end stack that fits the project; the docs do not standardise one.

<div class="q-callout q-callout-tip"><i class="fa-solid fa-lightbulb lead"></i>
  <div><b>The template is where styling meets content.</b> Your classes and markup live in the Liquid templates; your build stack turns your sources into the assets those classes need. Quilium renders the markup and serves the assets, and stays out of how you build them.</div>
</div>

## When Quilium re-renders

Quilium re-renders on **content** and **template** changes; building your assets is a separate concern on your own trigger.

- **Content changes** (an editor edits a block, an agent updates a collection entry) change the **data**, not the template. The next render reflects them; nothing is "built". An editor can publish all day without any build.
- **Template changes** change the markup the render pipeline emits. The next render reflects the new template.
- **Asset changes** (your CSS or JavaScript sources) are rebuilt by **your** stack, on your own trigger, into the static files Quilium serves. Quilium does not run that build.

Knowing which of these you just changed tells you what could have moved, and who is responsible for rebuilding it.

<div class="q-ph"><i class="fa-regular fa-terminal"></i><span><b>Placeholder:</b> confirm exactly what <code>quilium run</code> serves locally and how a saved template or content change becomes a fresh local render. Verify against the CLI.</span></div>

## Where to go next

<div class="q-cards">
  <a class="q-card reco" href="/en/docs/architecture"><span class="k">Recommended</span><span class="t">Architecture</span><span class="d">The full picture of how the parts fit.</span></a>
  <a class="q-card" href="/en/docs/templating-philosophy"><span class="t">Templating philosophy</span><span class="d">Why rendering is server-side and template-driven.</span></a>
  <a class="q-card" href="/en/docs/routing-and-urls"><span class="t">Routing and URLs</span><span class="d">How a URL resolves to a page and its data.</span></a>
</div>
