# How Consultiz Works

## How Consultiz Works

**Skill level:** Everyone · **Time:** 10 minutes

Read this page once and the rest of the theme stops being a mystery. Consultiz is built from a few simple ideas that repeat everywhere.

### The Big Picture
Consultiz is a **static site**: when you run `npm run build`, it turns your text files into finished HTML pages in `dist/`. There is no database and no admin panel. Your files _are_ the website.

```text
config.toml ──► site settings: name, URL, contact details, forms
menu.en.json ─► header and footer links
theme.css ────► colors, type scale, breakpoints

ROUTE  src/pages/[...lang]/pricing.astro
  │    which sections, in which order
  │
  ├─ PAGE  src/content/pricing/english/-index.md
  │        title, SEO, page header, named blocks
  │
  └─ each SECTION
       ├─ default: sections/english/faq-centered.md
       └─ + page block: corporateFaq: { ... }

Base.astro wraps every page:
  head · header · page · footer · cookie banner · scripts
```

### 1. Routes Decide What A Page Shows
Each file in `src/pages/[...lang]/` is one page (a **route**). It lists the sections that page shows, top to bottom. This is the pricing page, `src/pages/[...lang]/pricing.astro`, shortened:

```astro
<Base {...entry?.data}>
  <PageHeader content={entry?.data} />
  <PricingSection content={entry?.data.pricingSection} />
  <CustomersSection content={entry?.data.customersSection} />
  <FaqCentered content={entry?.data.corporateFaq} />
  <!-- ...more sections... -->
</Base>
```

To **reorder** sections, move a line. To **remove** a section from one page, delete its line. The `[...lang]` folder name means one file builds every language: English at `/pricing/`, French at `/fr/pricing/`.

### 2. Sections Have Default Content
Most sections are **reusable**: they read a default content file in `src/content/sections/<language>/`. For example, `FaqCentered.astro` reads `faq-centered.md`. That file holds the section's default text, lists, buttons, and options.

Edit a section file and the change appears **everywhere that section is used**. Set `enable: false` at the top of the file to hide the section on every page.

Some sections are **page-specific**: their content lives in the page's own file instead (the tax and accounting homepage, the solution and industry layouts, the webinar page). `docs/section-ownership.md` in the theme lists which is which.

### 3. Pages Can Override Any Section
A page file can change a reusable section **for that page only** with a **named block**. The pricing page uses this to give its FAQ a different title:

```yaml
# src/content/pricing/english/-index.md
---
title: "Pricing Plan"
corporateFaq:          # overrides src/content/sections/english/faq-centered.md
  title: "Questions about our plans"
---
```

Each page reads a fixed set of block names. The page file's comments, the theme's `README.md`, and [Sections](/consultiz/customization/sections/) list them.

A block with a wrong name, for example `faqSection:` instead of `corporateFaq:` on the pricing page, is ignored without an error. Copy block names from the comments or the tables in these docs.

<Aside type="caution" title="A block only works where the route uses it">
  Adding a block for a section the page doesn't render does nothing. The
  override controls change sections already on the page; they never insert a
  new one. Check the route file to see which sections a page shows.
</Aside>

### 4. How Overrides Merge
When a page block meets the section's default content, Consultiz merges them with these rules:

| You write in the page block                | Result                                                         |
| ------------------------------------------ | -------------------------------------------------------------- |
| A text or number (`title: "Hello"`)        | Replaces the default value                                     |
| An object (`button:`, `options:`)          | Merges key by key: only the keys you write change              |
| A list (`list:`, `slides:`, `inputs:`)     | Replaces the **whole** list. Write every item you want to keep |
| An empty string (`title: ""`)              | **Clears** the value. Leave the key out to keep the default    |
| An empty list (`list: []`)                 | Clears the list (for logos, articles, and teams, this hides the section) |
| `enable: false`                            | Hides the section on this page only                            |
| `enable: true`                             | Shows a section on this page even when its section file has `enable: false` |

So this block changes only the button label and keeps its URL, icon, and hover effect:

```yaml
ctaSection:
  button:
    label: "Talk to this office"
```

<Aside type="note">
  If a page block says `enable: true`, setting `enable: false` in the section
  file will not hide the section on that page. Change or remove the page
  block too.
</Aside>

### 5. Base Wraps Every Page
`src/layouts/Base.astro` adds the parts that every page shares:

- the `<head>`: title, description, canonical link, language alternates, Open Graph tags, structured data, fonts, and your `[head]` scripts
- the header, chosen by the route: the standard header, a transparent header over the homepage banner, or the tax and accounting header
- the footer, also chosen by the route: the standard footer, the homepage footer (`footer-newsletter-grid.md`), or the corporate "office" footer
- the cookie banner, the back-to-top button, the cursor follower, and shared scripts

### 6. Small Interface Text Lives In i18n Files
Labels that are not page content, such as form messages, slider controls, "Read more", or the footer copyright, live in `src/i18n/en.json` and `src/i18n/fr.json`. Many `config.toml` labels are empty on purpose (`label = ""`): empty means "use the translated text from the i18n file". Fill them in only if your site has one language.

### 7. Config Is Converted Before Astro Reads It
Astro cannot read TOML, so `npm run dev` and `npm run build` first convert `src/config/config.toml` into `.astro/config.generated.json`. While `npm run dev` is running, this happens every time you save. Always edit the TOML file, never the generated JSON.

Restart `npm run dev` after you change languages, folder names, `baseUrl`, or `trailingSlash`.

### 8. What Happens During A Build
<Steps>

1. `config.toml` is converted to JSON.
2. Astro checks the content files against their schemas in `src/content.config.ts`, including the named blocks in page frontmatter (`sectionsSchema` in `src/sections.schema.ts`). A wrong value type there stops the build with the file name and field.
3. Every route is rendered once per language into `dist/`.
4. The sitemap, `robots.txt`, the blog RSS feeds, `llms.txt`, `llms-full.txt`, and the Markdown copies of pages are written.
5. If `site.baseUrl` is empty, a yellow `[site]` warning prints and the sitemap is skipped.
6. Draft pages are removed from the sitemap.

</Steps>

<Aside type="caution" title="What the checks don't catch">
  Section files in `src/content/sections/` are checked only for a few common
  fields (`enable`, `title`, `button`, and similar). A misspelled option inside
  a section file, or a misnamed page block, is not reported. Look at the page in
  the browser after each change.
</Aside>

### Development vs. Production
| Feature                    | `npm run dev`                   | Built site (`npm run build`)              |
| -------------------------- | ------------------------------- | ----------------------------------------- |
| Pages with `draft: true`   | Shown, so you can preview them  | Not built                                 |
| Forms without an endpoint  | Disabled, with a "not configured" message | The same: visitors see the message |
| Site URL warning           | Not shown                       | Printed at the end of the build while `baseUrl` is empty |
| Sitemap                    | Not built                       | Built when `baseUrl` is set               |

### Find Where Any Text Comes From
See a sentence on the site and want to change it? Search the whole project for it: in VS Code press <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>F</kbd> (<kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>F</kbd> on Mac) and paste a few words. It will be in one of these places, checked in this order:

1. The page's own file, in a named block (`src/content/<page>/<language>/-index.md`)
2. The section's default file (`src/content/sections/<language>/`)
3. The interface text (`src/i18n/<language>.json`)
4. The menus (`src/config/menu.<language>.json`)
5. Site settings (`src/config/config.toml`)

If the same text appears in both a page block and a section file, the page block wins on that page.

<Aside type="tip" title="For developers">
  `NEXTJS-TO-ASTRO-GUIDE.md` in the theme walks through adding a section
  (component, Markdown defaults, schema, and route), creating a page, and
  reusing the button and image components.
</Aside>