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

Config Reference

File: src/config/config.toml · Skill level: Beginner

config.toml holds every site-wide setting. It is grouped into tables: a line in [brackets] starts a table, and every key = value line below it belongs to that table until the next one. The file has a comment beside most keys; this page explains them in one place.

In the Tina edition, these keys are under Site settings at /admin/. In the Sanity edition, most are under Site settings in the Studio, which win over this file. Favicons, the language settings, and the collection folder names stay in config.toml there.

Site Identity

Table: [site]

KeyWhat it does
titleSite name. Used in page titles, the logo’s alt text, structured data, llms.txt, and the outlined wordmark at the bottom of the wordmark footer
descriptionDefault description for search results and social previews. Empty uses each language’s own, in src/i18n/<lang>.json. A value here is used for every language.
taglineAdded after every page title (“Pricing - your tagline”). Empty uses each language’s own, in src/i18n/<lang>.json. A value here is used for every language. A page turns it off with disableTagline: true
taglineSeparatorText between title and tagline. Empty uses " - "
baseUrlYour live address, for example "https://www.your-domain.com". Ships as the placeholder "https://example.com", and npm run build warns until you change it. A SITE_URL environment variable on the build overrides it
logoPath to the logo for light backgrounds
logoAlternatePath to the logo for dark backgrounds: the dark footers, and the transparent header over a photo
logoTextText next to the logo. Empty shows only the image
logoWidth, logoHeightLogo size, for example "132px" and "32px"
trailingSlashtrue makes every URL end with / (/pricing/)
[site.favicon] imageSource image for npm run generate-favicons. Leave path as it is

Search Engines

Tables: [seo], [seo.robotsTxt], [seo.ai], [seo.localBusiness], [seo.sitemap]

KeyWhat it does
authorDefault author meta tag
keywordsDefault keywords for pages without their own keywords
robotsDefault robots meta tag. The shipped value lets search and AI answers quote and preview pages
[seo.robotsTxt] enableBuilds /robots.txt
[seo.robotsTxt] disallowPaths crawlers must skip, for example ["/drafts/"]
[seo.robotsTxt] aiSearchfalse asks the crawlers of AI answer engines (ChatGPT search, Claude, Perplexity, and others) not to fetch your pages
[seo.robotsTxt] aiTrainingfalse asks crawlers that collect content to train AI models to stay away
[seo.ai] llmsTxtBuilds /llms.txt and /llms-full.txt, one per language
[seo.ai] markdownPagesBuilds a Markdown copy of each service, project, post, open role, FAQ, pricing, and legal page at <page>.md
[seo.localBusiness] typeThe schema.org business type, for example "HomeAndConstructionBusiness", "Electrician", or "RoofingContractor"
[seo.localBusiness] areaServedThe towns or regions you install in. Ships with sample town names
[seo.localBusiness] priceRange, openingHoursOptional. openingHours uses the schema.org format, for example "Mo-Fr 08:00-18:00"
[seo.sitemap] enableBuilds /sitemap-index.xml
[seo.sitemap] excludeFolder names to leave out of the sitemap

The business name in the structured data is site.title; its address, phone, and email come from [settings.contactInfo]. Details: SEO & AI Visibility.

General Settings

Table: [settings]

KeyWhat it does
blogFolder, serviceFolder, projectsFolder, testimonialFolder, teamFolder, careersFolderFolder names of the collections. Changing one also means renaming the content and route folders and the collection in src/content.config.ts. Most sites keep them
paginationPosts per blog list page
stickyHeaderKeeps the header bar at the top of the window while you scroll. The rows above it (top bar, info row, announcement strip) scroll away; once the bar reaches the top, only its colours change
contactFormActionWhere the quote form sends its data. The shipped value is a placeholder, and npm run dev and npm run build print a [forms] warning until you change it. See Forms
contactFormProvider"formsubmit.co" (default), "formspree", or "netlify"
footerDescriptionText under the logo in the cta and contact footer layouts. Empty uses footer.description from src/i18n/<language>.json

Smooth Scroll

Table: [settings.smoothScroll]

Smooth scrolling powered by Lenis. It stays off on touch devices.

KeyWhat it does
enablefalse gives the browser’s normal scrolling
respectReducedMotionSwitches it off for visitors who ask for less motion
durationHow long the glide lasts. Higher feels slower
easingexpo, linear, easeOutQuad, or easeOutCubic
smoothWheel, syncTouch, wheelMultiplier, touchMultiplier, anchors, autoRaf, stopInertiaOnNavigateFiner settings. Smooth Scroll explains each one

Animations

Table: [settings.animation]

KeyWhat it does
enableFade-in animations as content scrolls into view, and the slow drift (parallax) of full-width photos. A page turns the fade-in off for itself with scrollReveal: false in its frontmatter, as the main homepage does
respectReducedMotionShows content without animation for visitors who ask for less motion
durationEmpty keeps each element’s own timing; a value such as "900ms" sets one duration for all
distance, blur, easingHow far content moves in, how blurred it starts, and with which curve
rootMargin, thresholdHow early an element starts animating

Cursor

Table: [settings.cursor]

enable = true adds an animated custom cursor that follows the mouse. It ships off, and it never shows on touch screens.

Table: [settings.cookieConsent]

KeyWhat it does
enableShows the cookie banner and holds consent-gated scripts until visitors choose
revisionRaise it by 1 when your cookie use changes, to ask every visitor again

Details: Cookies & Analytics.

Table: [settings.pageActions]

KeyWhat it does
enableThe Copy page, View as Markdown, and Ask links on blog posts and on service, project, and job pages. false also removes the footer row. The Markdown links need [seo.ai] markdownPages = true
footerThe Ask AI and llms row in every footer layout
providersAssistants offered: any of "chatgpt", "claude", "perplexity", "grok". Ships with all four. [] hides the “Ask” links

Details: AI Links & llms.

Theme Demo Settings

Table: [settings.layoutSwitcher]

This table is used only by the theme’s own demo site. It has no effect on your build, so leave it as it is. To change how a section looks, set options.layout in its content file: see Section Layouts.

Tables: [settings.footer], [settings.footer.band], [settings.footer.cta], [settings.footer.contact], [settings.newsletter]

KeyWhat it does
[settings.footer] layoutwordmark (default), newsletter, cta, or contact. A page’s footerLayout frontmatter wins
[settings.footer.band]The call-to-action band that overlaps the top of the newsletter and cta layouts (in the cta layout it is the photo band below). enable = false turns it off on every page; it also hides on its own on pages that show a call to action section. url is where its button goes, and also the quote row of the wordmark layout. image and imageAlt are the arch photo in the newsletter layout’s band (empty image hides it). Its text is footer.band in the i18n files
[settings.footer.cta]The photo band of the cta layout: enable, title, label, and url of its closing line and button, and image and imageAlt of its photo (empty image hides it). Empty title and label use footer.cta.title and footer.cta.button from the i18n files; the project card is footer.cta.projects
[settings.footer.contact]The area check of the contact layout: postcodes, the postcode prefixes you cover (the shipped ones are placeholders), and url, the quote page it links to. An empty postcodes list sends visitors to the quote page
[settings.newsletter]enable, action, and provider (formsubmit.co, formspree, netlify, or "" for a plain form post) of the sign-up form in the newsletter layout. The shipped action is a placeholder: npm run dev and npm run build print a [forms] warning until you change it. See Forms

Details: Footer.

Table: [settings.copyright]

enable shows the copyright line in the footer. text overrides footer.copyright from the i18n files; {{ year }} is replaced with the year of the build.

Theme Credit

Table: [settings.themeCredit]

The theme credit in every footer layout, and the last line of llms.txt. It has enable, text, and url, and it is the same in every language. The part of text in [brackets] links to url:

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

Languages

Table: [settings.multilingual]

KeyWhat it does
enablefalse builds only the default language
defaultLanguageLanguage served without a prefix ("en")
disableLanguagesLanguages to skip, for example ["fr"] or ["fr", "ar"]
showDefaultLangInUrltrue adds the prefix to the default language too (/en/pricing/)

Details: Internationalization.

Contact Details

Table: [settings.contactInfo]

address, email, phone, and hours. They are shown in the header’s contact row, the mobile menu, the footers, and the contact cards on /contact/, and they feed the structured data and llms.txt. Write them as plain text; the phone number becomes a tel: link on its own.

Mobile Menu Panel

Tables: [settings.headerOffcanvas], [settings.headerOffcanvas.button]

The slide-in panel that opens from the menu button on small screens: a short description, the menu links, your contact details, social icons, and a button. Empty description and label use headerOffcanvas from the i18n files.

Header Layout

Table: [settings.header]

layout: classic (default), transparent, floating, or promo. A page’s headerLayout frontmatter wins. See Header.

Header Button

Table: [settings.navigationButton]

The button at the right of the header (“Get a free quote”). It has enable, label, and url. An empty label uses navigation.buttonLabel from the i18n files.

Announcement

Table: [settings.announcementBar]

The citrus announcement strip at the top of the page. The promo header layout always shows it; enable = true also shows it above the classic header. label is the text for every language and accepts Markdown; empty uses header.announcement from the i18n files, and a page’s headerAnnouncement wins over both. See Header.

Tables Of Contents

Table: [settings.markup.tableOfContents]

enable, startLevel, endLevel, ordered, and expanded for an “On this page” list on blog posts and text pages such as the privacy policy. It ships off.

Social Previews

Table: [opengraph]

KeyWhat it does
imageShared preview image, used when a page has no image
ogLocale, ogTypeOpen Graph locale and type
twitter, twitterCardX (Twitter) handle and card type

Custom Head Scripts

Table: [head]

content is pasted into the <head> of every page. Use it for analytics, verification tags, or extra stylesheets. With the cookie banner on, mark tracking scripts so they wait for consent: see Cookies & Analytics.

Type something to search...