# Pages

## Pages

**Skill level:** Beginner to edit, light code to add a page made of sections

### Every Page And Its File
The route file decides which sections a page shows. The content file holds the page's title, SEO fields, page header, and named blocks. Paths below are for English. French uses the same files in `french/`, served under `/fr/`, and Arabic in `arabic/`, served under `/ar/`.

| Page                 | URL                         | Route (`src/pages/[...lang]/`) | Content (`src/content/`)                  |
| -------------------- | --------------------------- | ------------------------------ | ----------------------------------------- |
| Homepage             | `/`                         | `index.astro`                  | `homepage/english/-index.md` and the section files |
| Demo homepages       | `/home-two/`, `/home-three/`, `/home-four/` | `home-two.astro`, `home-three.astro`, `home-four.astro` | `homepage/english/home-two.md`, `home-three.md`, `home-four.md` |
| Services overview    | `/services/`                | `services/index.astro`         | `services/english/-index.md`              |
| Service page         | `/services/<customSlug>/`   | `services/[single].astro`      | `services/english/service-0X.mdx`         |
| Projects             | `/projects/`                | `projects/index.astro`         | `projects/english/-index.md`              |
| Project page         | `/projects/<customSlug>/`   | `projects/[single].astro`      | `projects/english/project-X.mdx`          |
| Pricing              | `/pricing/`                 | `pricing.astro`                | `pricing/english/-index.md`               |
| Savings calculator   | `/calculator/`              | `calculator.astro`             | `calculator/english/-index.md`            |
| About                | `/about/`                   | `about.astro`                  | `about-us/english/-index.md`              |
| Team                 | `/team/`                    | `team/index.astro`             | `team/english/-index.md`                  |
| Careers              | `/careers/`, `/careers/<role>/` | `careers/`                 | `careers/english/`                        |
| FAQ                  | `/faq/`                     | `faq.astro`                    | `faq/english/-index.md`                   |
| Blog                 | `/blog/`, posts, `/blog/page/<n>/`, `/blog/category/<name>/`, `/blog/tag/<name>/` | `blog/` | `blog/english/` |
| Contact and quote    | `/contact/`                 | `contact.astro`                | `contact/english/-index.md` and `sections/english/contact-section-two.md` |
| Legal and text pages | `/privacy-policy/`, `/terms-conditions/` | `[page].astro`    | `pages/english/*.md`                      |
| Shortcode demo       | `/components/`              | `[page].astro`                 | `pages/english/components.mdx`            |
| 404                  | any missing URL             | `404.astro` (and `src/pages/404.astro`) | `notFound` in `src/i18n/en.json` |
| RSS feed             | `/rss.xml`                  | `rss.xml.ts`                   | built from the blog posts                 |

Each collection (services, projects, careers, blog, team, testimonials) is explained in [Collections](/ecozen/customization/collections/).

### Page Header
Inner pages such as pricing, the calculator, contact, FAQ, team, careers, projects, and blog start with a page header: a small badge, the title, and a description. It is set by fields at the top of the page's content file:

```yaml
# src/content/careers/english/-index.md
badge: "Careers"
title: "Build the clean energy around you"
description: "We hire installers, electricians, and advisors who take pride in tidy work..."
headerImage: "/images/photos/cta-unsplash-pIcseKMisrs.jpg"   # optional photo under the header
headerImageAlt: "Two installers fitting solar panels on a roof"
headerAlign: "left"   # left | center
```

The about page and the services overview open with a section instead (the about intro, and the services band).

Service and project pages show the entry's title in the header. Their badge comes from `badgeSecondary` in `services/english/-index.md` and from the project's first category, and a project's header photo is its `image`.

### Fields Every Page Accepts
These frontmatter fields work on page and entry files. `src/content/_file_format.md` explains most of them; the full list is the `page` schema in `src/content.config.ts`.

| Field                     | What it does                                                         |
| ------------------------- | -------------------------------------------------------------------- |
| `title`, `description`    | The page title and summary                                           |
| `badge`                   | The small label above the title in the page header                   |
| `metaTitle`, `metaDescription` | Replace the title and description in search results only        |
| `image`                   | Social preview image for this page (and the photo on cards, for entries) |
| `draft`                   | `true` hides the page from the built site (it still shows in `npm run dev`) |
| `customSlug`              | A different URL segment than the file name. Use the same value in every language |
| `canonical`, `robots`, `keywords` | SEO overrides                                                |
| `excludeFromSitemap`, `excludeFromAi` | Leave the page out of the sitemap, or out of `llms.txt` and the Markdown copies |
| `disableTagline`          | Don't add the site tagline to this page's title                      |
| `footerLayout`            | `wordmark`, `newsletter`, `cta`, or `contact`: another footer on this page. See [Footer](/ecozen/customization/footer/) |
| `headerLayout`            | `classic`, `transparent`, `floating`, or `promo`: another header on this page. See [Header](/ecozen/customization/header/) |
| `headerAnnouncement`      | The announcement strip text on this page (Markdown) |
| `date`, `updated`         | Publish date and last meaningful edit, used in structured data       |

### Add A Page
<Tabs>
  <TabItem label="A text page (no code)">

    For policies, guides, or any page of text. Ecozen renders every file in `src/content/pages/` as a page.

    <Steps>

    1. Copy `src/content/pages/english/terms-conditions.md` to a new file, for example `src/content/pages/english/warranty.md`. The file name becomes the URL: `/warranty/`.

    2. Change `title`, `description`, `date`, and the Markdown body.

    3. Create a version in each other language folder of `src/content/pages/` with the **same file name**.

    4. Add a link to it in every `src/config/menu.*.json` file, for example in `footerSecondary`.

    </Steps>

  </TabItem>
  <TabItem label="A page made of sections (light code)">

    For landing pages that reuse Ecozen's sections. The demo homepages are the model: their routes read a file from the `homepage` collection, which accepts every named block.

    <Steps>

    1. Copy `src/pages/[...lang]/home-two.astro` to `src/pages/[...lang]/battery-offer.astro`. The file name becomes the URL: `/battery-offer/`.

    2. In the new route, change `getEntryCTM("homepage", "home-two", ...)` to `getEntryCTM("homepage", "battery-offer", Astro.currentLocale)`, and create `src/content/homepage/english/battery-offer.md` with a `title`, a `metaDescription`, and the named blocks you need, each with `enable: true`.

    3. Replace the sections inside `<Base>` with the ones you want, and pass each its block: `<FaqSection content={data.faqSection} />`.

    4. Create the content file in each other language folder of `src/content/homepage/` and add the page to the menus.

    </Steps>

    Don't create a section page from a file in `src/content/pages/`: every file there is also built as a text page at the same URL.

  </TabItem>
</Tabs>

### Remove A Page
1. Delete its route file in `src/pages/[...lang]/` and its content (file or folder) in `src/content/`, in every language.
2. Remove its links from every `src/config/menu.*.json` file and any content file or button that links to it (search the project for the URL).
3. Run `npm run astro-check`, then `npm run build`, to make sure nothing still points to it.

To hide a page without deleting it, set `draft: true` in its content file.

<Aside type="note">
  The homepages and the about page don't read `draft`. To remove a demo
  homepage, delete its files instead.
</Aside>