Skip to content
New: Customize your theme with an AI assistant. Read the guide

Sections

Files: src/content/sections/english/ (and the other language folders), page content files · Skill level: Beginner to edit, light code to add or move

A section is one full-width block of a page: a hero, a pricing table, an FAQ. Each section is two files that share a name:

src/layouts/components/sections/PricingSection.astro ← how it looks (component)
src/content/sections/english/pricing-section.md ← what it says (content)
src/content/sections/french/pricing-section.md
src/content/sections/arabic/pricing-section.md

How Ecozen Works explains the idea in full. This page is the practical reference.

Change A Section Everywhere

Edit its file in src/content/sections/english/ (and the other language folders). The comments in each file list its options and allowed values.

Section files have no schema, so npm run astro-check doesn’t catch a wrong value in them, such as a misspelled layout. Copy values from the comments, then check the page in the browser.

Hide A Section

  • Everywhere: set enable: false at the top of its section file.

  • On one page: add its block to that page’s file with enable: false:

    faqSection:
    enable: false
  • On one page, for good: delete its line in the page’s route file in src/pages/[...lang]/.

A page block can also turn a section back on for one page when the section file has enable: false.

Change A Section On One Page

Add a named block to the page’s content file, with enable: true and only the keys you want to change. The block name is in the table below. Remember the merge rules: objects merge key by key, lists replace the whole list, and "" clears a value.

Copy the block name exactly. A block with a wrong name, for example faqsSection: instead of faqSection:, is ignored without an error. npm run astro-check checks the values inside a correctly named block, except in the page files of src/content/about-us/, contact/, faq/, pricing/, and calculator/, which have no schema.

src/content/calculator/english/-index.md
faqSection:
enable: true
badge: "Questions"
title: "About your estimate"
list:
- enable: true
title: "How accurate is the estimate?"
content: "It is a fair starting point for a typical roof..."

Blocks Each Page Reads

PagePage fileBlocks the route reads
Main homepage /homepage/english/-index.mdctaSection
Commercial and farm /home-two/homepage/english/home-two.mdheroSection, companySection, comparisonSection, benefitsSection, impactSection, processSection, servicesSection, projectsSection, careersBandSection, blogSection, ctaSection
Renewable energy /home-three/homepage/english/home-three.mdheroSection, logoStripSection, statementSection, bentoSection, missionSection, featureSliderSection, impactSection, testimonialSection, blogSection, contactBandSection
EV and batteries /home-four/homepage/english/home-four.mdheroSection, tabsSection, chargeSpeedSection, pricingSection, projectsSection, faqSection, ctaSection
Aboutabout-us/english/-index.mdaboutIntroSection, missionSection, valuesSection, impactSection, whyUsSection, testimonialSection, ctaSection
Services overviewservices/english/-index.mdservicesSection, benefitsSection, testimonialSection, ctaSection
Service pageservices/english/<entry>.mdxctaSection
Projectsprojects/english/-index.mdctaSection (also used by every project page)
Project pageprojects/english/<entry>.mdxctaSection
Pricingpricing/english/-index.mdpricingSection, benefitsSection, faqSection, ctaSection
Calculatorcalculator/english/-index.mdcalculatorSection, faqSection, ctaSection
Teamteam/english/-index.mdteamSection, ctaSection
Careerscareers/english/-index.mdbenefitsSection, careersListSection, ctaSection
FAQfaq/english/-index.mdfaqSection, ctaSection
Contactcontact/english/-index.mdcontactSection, coverageSection, ctaSection
Text pagespages/english/<page>.mdctaSection

On /home-four/, the testimonials section reads testimonial-section.md directly: its route passes no block. Some blocks are read by the route but not set in the shipped homepage file, so those sections show their section files: the cost comparison and careers band on /home-two/, the statement, bento grid, feature slider, and contact band on /home-three/, and the charging speeds on /home-four/.

Add A Section To A Page

This is a small code edit in the page’s route file:

  1. Import the component at the top, between the --- lines:

    import FaqSection from "@/components/sections/FaqSection.astro";
  2. Place it where you want it, inside <Base>:

    <FaqSection />
  3. To give it page-specific content, read its block from the page file and pass it in:

    <FaqSection content={page?.data.faqSection} />

Building a brand-new section is a developer task: AGENTS.md explains the conventions (one .astro component, one content file in each language, and a schema in src/sections.schema.ts), so an AI assistant can do it for you.

Section Catalog

Every section, its content file in src/content/sections/<language>/, the block name a page uses to override it, and where it appears. Layout values are in Section Layouts.

Homepage And Marketing

Section (component)Content filePage blockUsed on
Hero (HeroSection)hero-section.mdheroSectionAll four homepages
Logo strip (LogoStripSection)logo-strip-section.mdlogoStripSectionMain and renewable energy homepages
About (CompanySection)company-section.mdcompanySectionMain and commercial homepages
Services (ServicesSection)services-section.mdservicesSectionMain and commercial homepages, /services/ (as its page header)
Benefits (BenefitsSection)benefits-section.mdbenefitsSectionMain and commercial homepages, services, pricing, careers
How it works (ProcessSection)process-section.mdprocessSectionMain and commercial homepages
Testimonials (TestimonialSection)testimonial-section.mdtestimonialSectionMain, renewable energy, and EV homepages, about, services
Results (ImpactSection)impact-section.mdimpactSectionMain, commercial, and renewable energy homepages, about
Projects (ProjectsSection)projects-section.mdprojectsSectionCommercial and EV homepages
Service area (CoverageSection)coverage-section.mdcoverageSectionMain homepage, /contact/
Cost comparison (ComparisonSection)comparison-section.mdcomparisonSectionCommercial homepage
Charging speeds (ChargeSpeedSection)charge-speed-section.mdchargeSpeedSectionEV homepage
Statement (StatementSection)statement-section.mdstatementSectionRenewable energy homepage
Bento grid (BentoSection)bento-section.mdbentoSectionRenewable energy homepage
Feature slider (FeatureSliderSection)feature-slider-section.mdfeatureSliderSectionRenewable energy homepage
Product tabs (TabsSection)tabs-section.mdtabsSectionEV homepage
Why choose us (WhyUsSection)why-us-section.mdwhyUsSectionMain homepage, about
FAQ (FaqSection)faq-section.mdfaqSectionMain and EV homepages, pricing, calculator, FAQ
Blog preview (BlogSection)blog-section.mdblogSectionMain, commercial, and renewable energy homepages
Careers band (CareersBandSection)careers-band-section.mdcareersBandSectionCommercial homepage
Contact band (ContactBandSection)contact-band-section.mdcontactBandSectionRenewable energy homepage
Call to action (CTASection)cta-section.mdctaSectionMost pages, above the footer. Off on the main and commercial homepages

Pages

Section (component)Content filePage blockUsed on
Pricing (PricingSection)pricing-section.mdpricingSection/pricing/, EV homepage
Savings calculator (CalculatorSection)calculator-section.mdcalculatorSection/calculator/, main homepage
Contact and quote form (ContactSectionTwo)contact-section-two.mdcontactSection/contact/
About intro (AboutIntroSection)about-intro-section.mdaboutIntroSection/about/
Mission (MissionSection)mission-section.mdmissionSection/about/, renewable energy homepage
Values (ValuesSection)values-section.mdvaluesSection/about/
Team (TeamSection)team-section.mdteamSection/team/
Open roles (CareersListSection)careers-list-section.mdcareersListSection/careers/
Project grid (ProjectsListSection)none: options in projects/english/-index.mdnone/projects/
Not found (NotFoundSection)none: text in notFound in the i18n filesnone404 pages

Two names don’t follow the pattern: the contact section’s file is contact-section-two.md but its block is contactSection, and the about section on the homepages is CompanySection / companySection.

Two more files in src/content/sections/ belong to widgets: cookie-consent.md, the site-wide cookie banner (Cookies & Analytics), and monitoring-panel.md, the text and numbers of the <MonitoringPanel /> shortcode (Writing Content).

Newer Sections In Detail

These sections came with the four homepages. Each one is a component in src/layouts/components/sections/ and a content file in src/content/sections/english/ (and the other language folders), and any route can use it.

Statement

File: statement-section.md · Block: statementSection

One large centered paragraph with small photos set inside the sentence. {1} and {2} in text mark where images[0] and images[1] go; a marker without a matching image is dropped. As the paragraph scrolls into view, the words turn from muted to ink one by one. With reduced motion on, the text shows in full ink.

text: "For 18 years we have built and run wind farms {1} and solar parks on land that stays in farming. Together with our battery sites {2} they send clean power to more than 400,000 homes."
images:
- image: "/images/photos/slide-wind-unsplash-H3fy5XIq9LM.jpg"
imageAlt: "Wind turbines in open farmland"
- image: "/images/photos/slide-storage-pexels-37061421.jpg"
imageAlt: "Equipment cabin beside a solar park"

Bento Grid

File: bento-section.md · Block: bentoSection

A heading, then one tall photo card beside icon cards. card holds the photo card: title, image, imageAlt, and a button. list holds the icon cards, each with icon, title, and description; four fill the grid.

Feature Slider

File: feature-slider-section.md · Block: featureSliderSection

A centered heading, then a text column with previous and next arrows beside a photo that changes with each item. subtitle is the heading at the top of the text column, and prevLabel and nextLabel are the screen-reader names of the arrows. Each item of list has a title, a description, and its own image (required) with imageAlt.

Contact Band

File: contact-band-section.md · Block: contactBandSection

A full-width photo (image, imageAlt) with a heading and text on the left and a white card with a short enquiry form on the right. form uses the same fields as the quote form (see Forms): emailSubject, submitButton, and inputs, including the two message items at the end. It sends through contactFormAction and contactFormProvider in config.toml, like the contact page.

A page can have the contact band and the quote form together: each form works on its own.

How It Works

File: process-section.md · Block: processSection

Numbered steps (plain numbers: 1, 2, 3) with a badge, title, description, and an optional button. Each item of list has a title, a description, a short meta note (for example “Within 2 working days”), and an optional image and imageAlt for the step card. Two layouts: steps (a row of cards) and timeline (a numbered list beside the section’s sticky image). See Section Layouts.

Product Tabs

File: tabs-section.md · Block: tabsSection

A heading, then tab buttons and one panel per tab. tabsLabel is the screen-reader name of the tab list. Each item of list has a label (the tab button), a title, a description, a check-mark list, an image with imageAlt, and a button. Without JavaScript, every panel shows, one below the other.

Projects

File: projects-section.md · Block: projectsSection

Case-study cards from src/content/projects/, each with its photo, title, and key facts, plus a button to /projects/.

options:
limit: 3 # number of project cards
projects: ["project-1", "project-6", "project-3"] # file names to show first, in this order

With projects empty, the section shows the projects with the lowest weight. Use the file name (project-1), not the customSlug.

Service Area

File: coverage-section.md · Block: coverageSection

Where you install: a heading and text, a list of towns or areas, a response-time line, a button, and a photo.

options:
layout: "list" # list | pills | regions
imagePosition: "right" # left | right
areasTitle: "Towns and areas we cover"
areas:
- "Riverside"
- "Oak Park"
responseTime:
icon: "Clock"
text: "**Typical response:** a reply within one working day and a home survey within 5 working days."
askText: "Not on the list?" # shown before the button
button:
enable: true
label: "Ask us"
url: "/contact/"
image: "/images/photos/project-home-unsplash-VX0ZEZSwqnY.jpg"
imageAlt: "Bungalow with a full array of solar panels on its roof"

list shows the areas as a check-mark list; pills shows them as rounded tags. imagePosition puts the photo on the left or the right. The sample towns are placeholders: list the places you really cover, and keep them in step with [seo.localBusiness] areaServed.

Towns by region. The regions layout groups your towns under a heading per region. It reads regions instead of areas:

options:
layout: "regions"
regions:
- name: "North district"
areas: ["Northgate", "Pine Ridge", "Cedar Hills", "Highfield"]
- name: "Central area"
areas: ["Riverside", "Oak Park", "Fairview", "Millbrook"]

Each region becomes a column with its name as a heading. Four regions fit one row when the section has no photo. The contact page uses this layout with image: "", so the regions sit in four columns, and points its button at the quote form on the same page. In src/content/contact/english/-index.md:

coverageSection:
enable: true
options:
layout: "regions" # list | pills | regions
badge: "Areas we serve"
title: "Towns we cover, by region"
areasTitle: ""
askText: "Don't see your town?"
button:
enable: true
label: "Get a quote"
url: "#contact-form"
variant: "fill"
image: "" # no photo, so the regions sit in four columns

The regions themselves come from coverage-section.md, so you keep one list of towns for the whole site. The sample regions are placeholders too. To hide the section on the contact page, set enable: false in this block.

Cost Comparison

File: comparison-section.md · Block: comparisonSection

A table that compares options side by side, with a footnote for the assumptions and a button. From the md breakpoint up it is a table; on phones each column becomes a card.

rowsLabel: "Per site" # heading of the row labels
recommendedLabel: "What we usually advise" # label on the recommended column
columns:
- title: "Grid only"
description: "Every kWh bought from your supplier"
recommended: false
- title: "Solar + battery"
description: "250 kWp and a 200 kWh battery"
recommended: true
rows:
- label: "Yearly energy bill"
values: ["$88,000", "$33,500"] # one value per column, in column order
footnote: "Assumptions: ..."

Give every row one value per column. The shipped figures are examples for a sample warehouse: replace them with figures you can stand behind, and keep the footnote’s assumptions true.

Charging Speeds

File: charge-speed-section.md · Block: chargeSpeedSection

One card per charger type, a button, and an optional note at the bottom.

labels:
range: "Range added per hour"
topUp: "Time to add 60 kWh"
suits: "Suits"
list:
- icon: "PlugZap"
title: "Home wallbox"
power: "7 kW"
range: ["About 30 miles", "About 50 km"] # one line each
topUp: "About 9 hours"
suits: "Most homes with one or two cars. Full by morning on a night tariff."
recommended: true # dark card
note:
enable: true
icon: "Moon"
title: "Off-peak:"
text: "a 6-hour night window on a 7 kW wallbox adds about 40 kWh..."

labels are the headings of the rows on every card. range is a list, so you can give miles and kilometres, or one line only. Mark one card recommended. The description above the cards states the assumptions behind the figures; keep it in step with them.

Type something to search...