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

Files: src/config/config.toml, src/i18n/en.json, src/config/menu.en.json, src/config/social.json, src/content/sections/english/cta-section.md · Skill level: Beginner

In the Tina edition, these are under Site settings, Menus, Social links, and Interface labels at /admin/. In the Sanity edition, they are in the Studio under Site settings, Menus, and Interface labels, and the section under Sections > CTA section.

Ecozen has four footer layouts. All of them read the same menus, services, social links, contact details, and text, so you can switch at any time.

src/config/config.toml
[settings.footer]
layout = "wordmark" # wordmark | newsletter | cta | contact
LayoutWhat it showsDemo page
wordmarkDark footer that opens with the logo and a large closing line. Beside it: rows for your phone, your email, and a quote link, each with an arrow. Below: Services, Pages, Visit us (address and opening hours), and Follow (social links as text) columns, the copyright and legal links, an outlined wordmark, and a line drawing of solar trackers along the bottom edge/
newsletterA citrus call-to-action band over the top edge, with a closing line, a button, your phone number, and an arch-shaped photo. Below, on a dark background with faint power-pylon drawings: logo, address, and social icons; your phone and email; Services; and a Subscribe column with the email sign-up form. Then the copyright and legal links/home-two/
ctaA photo band over the top edge, with a caption pill, a closing line, a button, and a card of current projects. Below, on a dark background: logo, description, and social icons; Pages; Legal; and Contact (address, email, phone, and opening hours). Then the copyright and a row of line-drawn wind turbines with turning blades/home-three/
contactLight footer that opens with a mint dotted panel: a reply-time line, your phone number in large type, your email, address, and opening hours, and a card where visitors check if you work in their postcode. Below it: logo, description, and trust pills; Pages, Services, and Legal columns; the copyright and social icons/home-four/

The wordmark is [site] title. The dark layouts, wordmark, newsletter, and cta, use the light logo (logoAlternate); contact uses the normal one (logo). The solar trackers tilt slowly to follow the sun and the turbine blades turn. The outlined wordmark rises into place as it scrolls into view, in browsers that support scroll-linked motion. All of these stand still for visitors who turn on reduced motion.

One page, another layout. Add footerLayout to the page’s frontmatter. It wins over [settings.footer] layout:

---
footerLayout: "cta" # wordmark | newsletter | cta | contact
title: "Wind, solar, and storage developer"
---

Each demo homepage sets its own: / uses wordmark, /home-two/ uses newsletter, /home-three/ uses cta, and /home-four/ uses contact. Every other page uses [settings.footer] layout, which ships as wordmark. If you keep one homepage, remove its footerLayout line or set it to the layout you use everywhere. It works on any page whose frontmatter reaches <Base>, which every shipped route does except the 404 pages. npm run astro-check reports a misspelled value in files that have a schema.

Edit footer in src/i18n/en.json (and the file for each other language):

"footer": {
"description": "Solar panels, battery storage, and EV charging for homes and businesses.",
"copyright": "© {{ year }} Ecozen. All rights reserved.",
"company": "Company",
"social": "Social",
"contact": "Contact",
"phone": "Phone",
"email": "Email",
"address": "Address",
"hours": "Opening hours",
"hoursText": "",
"newsletter": { ... },
"cta": { ... },
"contactPanel": { ... },
"band": { ... },
"statement": { ... },
"subscribe": "Subscribe"
}
  • {{ year }} becomes the year of the build, so the year updates each time you rebuild the site.
  • The copyright accepts Markdown links. Replace the shipped name with your own business.
  • description is the short text under the logo in the cta and contact layouts.
  • The Pages, Services, and Legal headings are common.pages, common.services, and common.legal.
  • phone and email label the phone and email rows of the wordmark and newsletter layouts. contact is the heading of the Contact column in the cta layout. address, email, phone, and hours name its rows for screen readers.
  • hoursText replaces the opening hours from [settings.contactInfo] hours for one language, for example "Lun–Ven, 8h00–18h00" in fr.json. Empty uses hours.
  • subscribe is the heading of the sign-up column in the newsletter layout.
  • statement, band, newsletter, cta, and contactPanel hold the text of each layout. They are described with each layout below.
  • company and social are not shown by the current footer layouts. You can leave them as they are.
  • For a one-language site you can set the text in config.toml instead: footerDescription under [settings], and text under [settings.copyright]. [settings.copyright] enable = false hides the line.
PartWhere it comes fromLayouts
Pages linksfooterSecondary in src/config/menu.en.jsonwordmark, cta, contact
Services linksYour first six services by weightwordmark, newsletter, contact
Legal linksfooterPrivacy in src/config/menu.en.jsonAll four
Social linksThe first four enabled links in src/config/social.jsonAll four
Phone, email, address, hours[settings.contactInfo] in src/config/config.tomlAll four (each shows a different mix)

See Menus for the link lists. "enable": false hides a link. An empty value in [settings.contactInfo] hides its row.

The AI Row And The Theme Credit

All four layouts end with the same two extras, placed by src/layouts/components/global/footer/FooterBottom.astro.

The AI row (FooterAi.astro) has Ask AI links that open an assistant with a question about the current page, and links to the page’s Markdown copy, llms.txt, and llms-full.txt. Change it in [settings.pageActions]: footer = false removes the row, and providers sets the assistants. Its words are ai.footerAsk, ai.footerRead, and ai.footerMarkdown in the i18n files. See AI Links & llms.

The theme credit (FooterCredit.astro) is editable in config.toml, and it is the same in every language. The part of text in [brackets] becomes the link:

[settings.themeCredit]
enable = true
text = "..."
url = "..."

Wordmark Layout

The large closing line and the quote row come from footer.statement in the i18n files:

"statement": {
"title": "Your roof can power more of your home than you think.",
"text": "Free roof survey, fixed price",
"button": "Get a free quote",
"visit": "Visit us",
"follow": "Follow",
"top": "Back to top"
}
KeyWhat it does
titleThe large closing line under the logo
text, buttonThe small label and the link text of the quote row. It links to [settings.footer.band] url
visitThe heading of the column with your address and opening hours
followThe heading of the column with your social links
topNot shown by the current layout. You can leave it as it is

The phone and email rows show phone and email from [settings.contactInfo]. The Follow column lists your social links by their label, as text with an arrow.

The newsletter and cta layouts open with a rounded call-to-action band. Its top half sits over the end of the page and its bottom half over the footer. Set it in config.toml:

[settings.footer.band]
enable = true
url = "/contact/" # the button link; also the quote row of the "wordmark" layout
image = "/images/photos/your-photo.jpg" # the arch photo of the "newsletter" layout; empty hides it
imageAlt = "Describe the photo"
  • enable = false removes the band from both layouts.
  • The band hides on its own on pages that have a call-to-action section, so the page doesn’t close with two calls to action in a row. See The Call To Action Above The Footer below.
  • In the newsletter layout the band text comes from footer.band in the i18n files. In the cta layout it is the photo band described under CTA Layout below.
"band": {
"title": "Have questions about going solar? We're here to help.",
"button": "Get a free quote",
"help": "Need any help?"
}

title is the closing line and button the button text. help is the small line above your phone number, which comes from [settings.contactInfo] phone. Without a phone number, the phone link hides. The arch photo shows on large screens only.

Newsletter Layout

Below the footer band, the left column shows the light logo, your address, and social icons. Next come your phone and email from [settings.contactInfo] as links, then your Services, then a Subscribe column with the sign-up form. The bottom row has the copyright and the legal links (footerPrivacy).

The sign-up form is set in config.toml:

[settings.newsletter]
enable = true
action = "https://formsubmit.co/[email protected]" # placeholder: set your own
provider = "formsubmit.co" # formsubmit.co | formspree | netlify | ""
provideractionHow it sends
"formsubmit.co"https://formsubmit.co/[email protected]In the background, with a status message under the field
"formspree"https://formspree.io/f/your-form-idIn the background, with a status message
"netlify""/"In the background, as a Netlify form named newsletter
""Any other sign-up URL, for example a mailing-list tool’s form URLA normal form post to that address

The form sends one field, email. A mailing-list tool that expects a different field name needs a small change in src/layouts/components/widgets/NewsletterForm.astro; test a sign-up after you connect it. enable = false, or an empty action, removes the whole Subscribe column. Its text is in footer.newsletter in the i18n files:

"newsletter": {
"label": "Energy tips and project news, once a month.",
"emailLabel": "Email address",
"placeholder": "Enter your email",
"button": "Subscribe",
"submitting": "Sending…",
"success": "Thanks. Please check your inbox to confirm.",
"error": "We couldn't sign you up. Please try again or email us.",
"subject": "New newsletter sign-up",
"note": "One email a month. Unsubscribe anytime."
}

label is the line above the field and note the small line under it. The submit button shows an arrow icon; button is its name for screen readers. emailLabel names the field for screen readers. submitting, success, and error are the status messages, and subject is the subject line of the email you receive from formsubmit.co or formspree.

CTA Layout

The cta layout opens with a photo band in the footer band position. Its photo, closing line, and button are set in config.toml:

[settings.footer.cta]
enable = true
title = "" # empty uses footer.cta.title from the i18n files
label = "" # empty uses footer.cta.button
url = "/contact/"
image = "/images/photos/your-photo.jpg" # the photo behind the band; empty hides it
imageAlt = "Describe the photo"

Leave title and label empty for a site in several languages and write the text in footer.cta.title and footer.cta.button in each file in src/i18n/. enable = false, or [settings.footer.band] enable = false, hides the whole photo band. Put the photo in src/assets/images/ like your other images, and describe it in imageAlt. The photo settles from a slight zoom as the footer scrolls into view.

The caption pill and the project card come from footer.cta in the i18n files:

"cta": {
"title": "Clean power, built to run for decades.",
"button": "Work with us",
"caption": "Ridge wind farm · 24 MW · operating",
"projectsTitle": "Current projects",
"projects": [
{ "name": "Hillside solar park", "size": "32 MW", "status": "Operating", "live": true },
{ "name": "Coastal wind farm", "size": "18 MW", "status": "Building" },
{ "name": "Valley battery site", "size": "40 MWh", "status": "Planning" }
]
}
KeyWhat it does
captionThe small pill above the closing line. Empty hides it
projectsTitleThe heading of the project card
projectsOne row per project: name, size, and a status pill. "live": true fills the pill with the brand color; leave it out for an outlined pill. An empty list ([]) hides the whole card

The sample projects are placeholders. List your own, or set "projects": []. Change them in every language file.

Below the band, the Contact column shows address, email, phone, and hours from [settings.contactInfo].

Contact Layout

The mint panel shows phone, email, address, and hours from [settings.contactInfo] in config.toml. The phone number is shown large and, like the email, becomes a link. The email, address, and hours sit in small pills. To show the opening hours differently in one language, write them in footer.hoursText in that language’s i18n file; empty uses hours. An empty value hides its row.

Area check. The card on the right asks for a postcode and answers on the spot whether you work there. Set the postcodes you cover and the quote page in config.toml:

[settings.footer.contact]
url = "/contact/" # the quote page the answer links to
postcodes = ["SP1", "SP2", "RV4", "GF7"] # placeholder: the postcode prefixes you cover
  • Each value is the start of a postcode. "SP1" matches SP1 4AB and sp14ab: case and spaces don’t matter. A prefix also matches longer ones, so "SP1" matches SP12 3CD too.
  • After the answer, a link sends the visitor to url with the postcode they typed.
  • With an empty list (postcodes = []), or when JavaScript is off, the form doesn’t answer. It opens the quote page instead.
  • The shipped postcodes are placeholders. Replace them with your own, or empty the list.

The panel’s text is in footer.contactPanel in the i18n files:

"contactPanel": {
"status": "Replies within 2 working hours",
"areaTitle": "Do we install in your area?",
"areaText": "Enter your postcode to check before you ask for a quote.",
"areaLabel": "Postcode",
"areaPlaceholder": "Postcode",
"areaButton": "Check",
"areaYes": "Good news: we install in {postcode}.",
"areaNo": "{postcode} is outside our usual area, but we may still cover it.",
"areaLink": "Ask for a quote",
"badges": ["Certified installer", "10-year workmanship warranty", "Fully insured"]
}
KeyWhat it does
statusThe short line with a dot above the phone number, for example your reply time
areaTitle, areaTextThe heading and the line of text of the area-check card
areaLabelThe name of the postcode field for screen readers
areaPlaceholder, areaButtonThe hint inside the field and the button text
areaYes, areaNoThe answer when the postcode is or isn’t on your list. {postcode} is replaced with what the visitor typed
areaLinkThe link after the answer
badgesThe trust pills under the footer description. An empty list ([]) hides them. Only list what is true for your business

src/config/social.json lists your profiles. Change url, or set enable: false to hide one:

{
"main": [
{
"enable": true,
"label": "Linkedin",
"url": "https://www.linkedin.com/company/your-company"
}
]
}

label picks the icon. These labels have one: Facebook, X, Twitter, Linkedin, Instagram, Github, Youtube, Pinterest, and Dribbble. The demo uses X, which shows the X logo. The footer shows the first four enabled links, so put the ones you care about first: as icons in the newsletter, cta, and contact layouts, and as text links named by label in the Follow column of the wordmark layout. The mobile menu panel uses the same file.

Most pages end with a call-to-action band above the footer: a photo, a badge, a title, a short text, and a button. Its default content is src/content/sections/english/cta-section.md:

---
enable: true
options:
layout: "band" # band | split
badge: "Free roof survey"
title: "Find out what your roof can save"
description: "Book a free roof survey. You get a panel layout, a fixed price, and yearly savings within two working days."
image: "/images/photos/band-cta-unsplash-Ilpf2eUPpUE.jpg"
imageAlt: "Aerial view of a solar array in green fields"
buttons:
- enable: true
label: "Get a free quote"
url: "/contact/"
variant: "fill"
class: "btn-accent"
showPhone: false # true adds the phone number from [settings.contactInfo]
---

Each route places the band itself, so a page can change it with a ctaSection block in its own file. The contact, calculator, careers, and projects pages already do. For example, in src/content/contact/english/-index.md:

ctaSection:
enable: true
badge: "Not ready to talk yet?"
title: "Estimate your savings first"
buttons:
- enable: true
label: "Open the calculator"
url: "/calculator/"
variant: "fill"
class: "btn-accent"

It has two layouts, set with options.layout:

LayoutWhat it looks like
bandThe default. A full-width photo with the badge, title, text, and buttons on a glass card in the middle
splitA light mint panel with rounded corners: the badge, title, text, and buttons on the left, and the photo in a rounded frame on the right, with no overlay. On small screens the photo moves below the text

In both layouts the photo moves a little slower than the page as you scroll.

The pricing page uses split, with two buttons. In src/content/pricing/english/-index.md:

ctaSection:
options:
layout: "split" # band | split
badge: "Your price"
title: "Get a fixed price for your roof"
image: "/images/photos/your-photo.jpg"
imageAlt: "Describe the photo"
buttons:
- enable: true
label: "Get a free quote"
url: "/contact/"
variant: "fill"
- enable: true
label: "Estimate savings"
url: "/calculator/"
variant: "outline"

The page’s buttons replace the default ones: a dark fill button and an outline one read well on the light panel. showPhone: true works in both layouts.

To hide it on one page, write enable: false in that page’s ctaSection block. The ctaSection block in src/content/projects/english/-index.md also applies to every project page. Blog pages always use the default band, and the 404 and job pages have none.

The homepages / and /home-two/ turn the band off with enable: false, and /home-three/ has none, so their footers close the page instead. On a page that keeps this band, the footer band of the newsletter and cta layouts hides, so the page doesn’t end with two calls to action.

Do It With AI

Set the footer to the [wordmark | newsletter | cta | contact] layout in [settings.footer] of
src/config/config.toml, and remove footerLayout from the homepage files I keep. Change
footer.description, footer.copyright, footer.statement, and footer.band in every file in src/i18n/
for my business "[NAME]" (keep {{ year }}). Set [settings.footer.band] url to my quote page. [For the newsletter layout: set [settings.newsletter] action to [URL] and
provider to [PROVIDER].] [For the contact layout: set [settings.footer.contact] postcodes to
[POSTCODE PREFIXES] and rewrite footer.contactPanel (badges: [MY REAL CERTIFICATIONS]).] [For the
cta layout: set [settings.footer.cta] image and imageAlt to [PHOTO], and footer.cta.caption and
footer.cta.projects to [MY PROJECTS], in every i18n file.] Update src/config/social.json with my profiles: [LINKS], and disable the
others. Then rewrite cta-section.md in every language folder of src/content/sections/ for my business,
keeping every key and option.
Type something to search...