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: your business details, the header and footer layouts, the forms, the estimator and booking rules, SEO, and more. 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. Most keys have a comment beside them; this page explains them all in one place, with the value Homio ships.

Values marked # sample or PLACEHOLDER in the file must be replaced before you launch.

Site Identity

Table: [site]

KeyShips asWhat it does
title"Homio"Brand name. {brand} in the footer copyright, structured data, social cards, and the business name when [business] name is empty. The home page title comes from its own metaTitle
descriptionA theme descriptionDefault description for search results and social previews
taglineA theme taglineAdded to every page title (“Pricing - your tagline”) and social titles. Replace it with a short line about your business. A page turns it off with disableTagline: true
taglineSeparator""Text between page title and tagline. Empty uses " - "
baseUrl"https://example.com"Placeholder. Your live address. Canonical links, the sitemap, robots.txt, RSS feeds, llms.txt, and social URLs are built from it, and npm run build warns while it is example.com. A SITE_URL environment variable on the build overrides it
logo""Path to a logo image that replaces the built-in mark (SVG or PNG). Empty draws the mark from src/lib/brandMark.ts
logoText"homio"Text next to the mark, shown exactly as typed
logoWidth, logoHeight"28px"Logo image size. Used only when logo is set
trailingSlashtrueURLs end with / (/pricing/). Restart the dev server after a change
[site.favicon] path"/images/favicons"Where the generated favicons go. Leave it as it is
[site.favicon] image"/images/favicon.svg"Source image for npm run generate-favicons (src/assets/images/favicon.svg)

Details: Site Identity & Logo.

Business Details

Tables: [business], [business.address], [business.geo], [business.hours]

One source for your company name, phone, email, address, and opening hours. The header, the mobile action bar, the footer, the contact page, the area pages, the booking form, the structured data, and llms.txt all read them from here.

KeyShips asWhat it does
name""Business name. Empty uses site.title
legalName""Optional legal name for structured data
type"LocalBusiness"The schema.org business type
phone"+15550100199" (sample)Phone for call links, in E.164 format. Empty hides every call link
phoneDisplay"(555) 010-0199" (sample)How the phone is written on the page
sms, smsDisplaysample numbersOptional number for “Text” links. Empty hides them
email"[email protected]"Placeholder. Your email
priceRange"$$"Shown in structured data
timezone"America/New_York"Time zone for “Open now” and booking dates
closedDatestwo sample holidaysDays with no bookings (YYYY-MM-DD)
[business.address]sample addressshow, street, locality, region, postalCode, country. show = false hides the street and postal code everywhere
[business.geo]emptyOptional latitude and longitude
[business.hours]sample hoursmon to sun, 24-hour "HH:MM-HH:MM". Empty is closed

Every key, its format, and where it appears: Business Info.

Search Engines

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

KeyShips asWhat it does
author""Default author meta tag. Empty uses the business name
keywords8 samplesDefault keywords for pages without their own keywords. Use your services and towns
robots"index, follow, max-snippet:-1, ..."Default robots meta tag. Lets search and AI answers quote pages and show images in full
[seo.schema] enabletrueStructured data (JSON-LD) on every page: business, website, page, and services, areas, and prices where they apply
[seo.schema] faqPagetrueFAQ markup on /faq/
[seo.robotsTxt] enabletrueBuilds /robots.txt
[seo.robotsTxt] disallow[]Paths crawlers must skip
[seo.robotsTxt] aiSearchtruefalse asks AI answer engines (ChatGPT search, Claude, Perplexity, and others) not to fetch your pages
[seo.robotsTxt] aiTrainingtruefalse asks crawlers that collect content to train AI models to stay away
[seo.robotsTxt] contentSignalsfalsetrue adds a Content-Signal line with the two choices above
[seo.ai] llmsTxttrueBuilds /llms.txt and /llms-full.txt per language, with your business facts first
[seo.ai] markdownPagestrueA Markdown copy of each service, area, project, post, job, pricing, FAQ, and guarantee page at <page>.md
[seo.ai] indexNowKey""An 8 to 128 character key turns on IndexNow; run npm run indexnow after each deploy
[seo.sitemap] enabletrueBuilds /sitemap-index.xml
[seo.sitemap] exclude["book/thanks"]Folder names to leave out of the sitemap

Details: SEO & AI Visibility.

General Settings

Table: [settings]

KeyShips asWhat it does
blogFolder"blog"Folder name of the blog. Changing it also means renaming the folders in src/content/ and src/pages/[...lang]/ and the collection in src/content.config.ts. Most sites keep it
servicesFolder"services"The same, for services
blogPagination6Posts per blog list page
pagination8Items per page on other paginated lists
stickyHeadertrueKeeps the header pinned while scrolling (the announcement bar scrolls away)
contactFormAction"https://formsubmit.co/[email protected]"Placeholder. Where the contact form (and, by default, the booking form) sends its data. npm run dev and build warn until you change it
contactFormProvider"formsubmit.co""formsubmit.co", "formspree", or "netlify"
footerDescription""Footer description. Empty uses footer.description from src/i18n/<language>.json

Details: Forms.

Table: [settings.layout]

KeyShips asValues
header"default"default, simple, centered, utility
footer"default"default, minimal, large, columns

A page’s headerLayout or footerLayout frontmatter wins. See Header & Mobile Bar and Footer & CTA Band.

Smooth Scroll

Table: [settings.smoothScroll]

Smooth scrolling powered by Lenis. It ships off (enable = false): the site uses the browser’s normal scrolling. respectReducedMotion keeps it off for visitors who ask for less motion; duration (1.1, higher feels slower) and easing (expo, linear, easeOutQuad, easeOutCubic) set the feel. Leave smoothWheel, syncTouch, wheelMultiplier, touchMultiplier, anchors, autoRaf, and stopInertiaOnNavigate as they are unless you know Lenis.

Light And Dark Mode

Table: [settings.colorScheme]

KeyShips asWhat it does
default"system"system (follows the visitor’s device), light, or dark, until a visitor picks one
switchertrueShows the light/dark button in the header, the mobile menu, and the footer

Details: Colors & Fonts.

Table: [settings.cookieConsent]

KeyShips asWhat it does
enabletrueShows the cookie banner and holds data-consent scripts until visitors choose
revision1Raise it by 1 when your cookie use changes, to ask every visitor again

The banner’s copy is in src/content/sections/english/cookie-consent.md (and french/). If you turn the banner off, also set enable to false on the “Cookie settings” item in the Legal column of the footer menus. Details: Cookies & Analytics.

Table: [settings.pageActions]

KeyShips asWhat it does
enabletrueThe Copy page menu on blog posts: copy as Markdown, open the Markdown copy, or ask an assistant. Needs [seo.ai] markdownPages
footerfalseA footer row with AI links and llms.txt on every page. Off for most local businesses
providers["chatgpt", "claude", "perplexity", "grok"]Assistants offered in “Ask”. Empty hides the “Ask” links

Animations

Table: [settings.animation]

Content fades in with a small rise as it scrolls into view, once.

KeyShips asWhat it does
enabletrueTurns the reveal animations on or off
respectReducedMotiontrueShows content without animation for visitors who ask for less motion
easing"cubic-bezier(0.215, 0.61, 0.355, 1)"The animation curve
duration"600ms"Reveal duration
distance"0.75rem"How far content rises while fading in
rootMargin, threshold"0px 0px -8% 0px", 0.14How early an element starts animating

Details: Animations.

Estimator

Table: [settings.estimator]

The instant estimator on the pricing page, the service pages, and the estimate sections. Rates, discounts, and add-ons are not here: they are in src/content/pricing/.

KeyShips asWhat it does
enabletrueTurns the estimator on
currency"USD"ISO 4217 currency code, one for every language
currencyDisplay"symbol"symbol ($ or $US), narrowSymbol ($ in every language), or code (USD)
bookUrl"/book/"Where “Book this visit” goes, with the selection in the address
ticketPrefix"EST"Code on the estimate ticket, for example EST-4K7Q2
animateTotaltrueCounts between totals. Always off for visitors who ask for less motion

Details: Pricing & Estimator.

Booking Request Form

Table: [settings.booking]

The form on /book/. It posts through the same provider as the contact form (contactFormProvider); its copy is in src/content/sections/english/booking-section.md.

KeyShips asWhat it does
enabletrueTurns the booking form on
formAction""Endpoint for booking requests. Empty uses contactFormAction. Set it to send bookings to another inbox or form
thankYouUrl"/book/thanks/"Where the form lands when JavaScript is off
minLeadDays1Earliest date: today plus this many days
maxDays60Latest date: today plus this many days
zipPattern"^\\d{5}$"Postal code check (a regular expression). UK example: "^[A-Za-z0-9 ]{5,8}$"
checkAreatrueTells visitors whether their ZIP code is in one of your service areas

Details: Booking Request.

Layout Switcher (Demo Only)

Table: [settings.layoutSwitcher]

enable = true adds a floating Change layout button that previews every layout of the section in view. It is for the theme’s demo site. Keep enable = false on your own site: the pages then render only the layouts chosen in your content files. To change how a section looks, set options.layout: see Section Layouts.

Table: [settings.copyright]

enable (true) shows the copyright line in the footer. text ("") overrides footer.copyright from the i18n files for every language. In both, {year} becomes the year of the build and {brand} the site.title.

Newsletter

Table: [settings.subscription]

The Mailchimp signup used by the newsletter section on the blog, the default and large footers, and the CTA band’s newsletter layout.

KeyShips asWhat it does
enabletruefalse hides every signup form and the newsletter section
title""Empty uses subscription.title from the i18n files
note""The consent line under the field. Empty uses subscription.note
formActiona placeholder URLPlaceholder. Your Mailchimp embedded form action. Change each &amp; in the copied URL to &. npm run dev shows a warning inside each form until it is set
mailchimpTagValue""Optional Mailchimp tag id added to every signup

Languages

Table: [settings.multilingual]

KeyShips asWhat it does
enabletruefalse builds only the default language. Then run npm run remove-multilingual to delete the French files
defaultLanguage"en"Language served without a prefix
disableLanguages[""]Languages to skip, for example ["fr"]
showDefaultLangInUrlfalsetrue adds the prefix to the default language too (/en/pricing/)

Restart the dev server after any change here. Details: Internationalization.

Header Button

Table: [settings.navigationButton]

The main button at the right of the header. The mobile action bar uses the same button.

KeyShips asWhat it does
enabletrueShows the button
label""Empty uses navigation.buttonLabel from the i18n files (“Get a price”). A value here is used in every language
url"/book/"Where it goes. The button is hidden on that page itself

Mobile Action Bar

Table: [settings.mobileActionBar]

The bar fixed to the bottom of the screen on phones (below 768 px), with Call and the header’s main button.

KeyShips asWhat it does
enabletrueShows the bar
showCalltrueThe Call button, with [business] phone. Hidden when the phone is empty
showTextfalseA Text button. Needs [business] sms
hideOn["/book/", "/contact/"]Path prefixes where the bar is left out (without the language prefix)
hideNearFootertrueThe bar slides away while the footer is visible

Details: Header & Mobile Bar.

Table: [settings.navigationSecondaryLink]

A text link before the header button, in every header layout from 1320 px wide. It ships off (enable = false). label ("") uses navigation.secondaryLabel (“Contact”); url is "/contact/".

Code Blocks And Tables Of Contents

Tables: [settings.markup.codeBlocks], [settings.markup.tableOfContents]

  • [settings.markup.codeBlocks] theme: auto (follows light and dark mode, the default) or dark (a dark code window in both modes), for fenced code in Markdown.
  • [settings.markup.tableOfContents]: the “On this page” list on blog posts and text pages such as the privacy policy. It ships with enable = true, startLevel = 1, endLevel = 5, ordered = false, and expanded = false.

Social Previews

Table: [opengraph]

KeyShips asWhat it does
image"/images/og-image.jpg"Shared preview image (public/images/og-image.jpg), used when a page has no image and no generated card
generateImagestrueDuring npm run build, renders a 1200×630 card (logo, section, title, description) for every page without an image
theme"light"light or dark palette for the generated cards and npm run generate-og-image
ogLocale"en_US"Fallback locale. Each language sets its own ogLocale in src/config/language.json
ogType"website"Open Graph type
twitter, twitterCard"", "summary_large_image"X (Twitter) handle and card type

Details: Site Identity & Logo.

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, change each tracking <script> to <script type="text/plain" data-consent="analytics"> (or "marketing") so it waits for consent; the comment above [head] shows an example. See Cookies & Analytics.

The Other Files Insrc/config/

FileWhat it holdsPage
menu.en.json, menu.fr.jsonThe header menu (with the Services and Areas dropdowns) and the footer link columnsMenus
language.jsonThe languages: name, code, content folder, order, and ogLocaleInternationalization
fonts.jsonThe three fonts: body, headings, and numbersColors & Fonts
social.jsonSocial links and their icons (main list)Footer & CTA Band

Colors are not in src/config/: they are tokens in src/styles/theme.css.

Do It With AI

Explain each table of src/config/config.toml in one line, then list every value marked
"# sample" or "PLACEHOLDER" that I must replace before launch, and the current value of each.
Don't change anything yet.
Type something to search...