Site config
Every key src/site.config.ts exports: site (a SiteConfig), features (a StommeFeatures) and listings (a Listing[]), all typed by @gronare/stomme/config.
astro.config.mjs passes them to the integration, stomme cms reads the file for the CMS, and the pages pass site and features to the block renderer. A key left out takes its default, so a site sets only what differs.
site
| Key | Default | What it does |
|---|---|---|
url |
none | the site's address, such as https://example.com; the calendar feed builds its event links from it ahead of site in astro.config.mjs, and breadcrumb JSON-LD uses it when site is unset |
routes.services |
/services |
where service pages are served |
routes.towns |
/areas |
where area pages are served |
routes.blog |
/blog |
where blog posts and the calendar feed are served |
routes.contact |
/contact |
where area, service and catalog entry pages send their buttons |
routes.formSuccess |
/thanks |
the thank-you page the contact form opens; it is always marked noindex |
routes.<name> |
none | a route of your own, such as routes.shop; every key under routes is passed to the routes manifest and CMS editors of an outside directory |
locale |
en-US |
the site's language and region; formats dates and picks the built-in interface text (English, Swedish or Norwegian); left unset, the interface text follows cmsLocale and dates format as en-US |
locales |
none | the content languages, default first; fewer than two turns translation off, see Translate a site |
localeTags |
none | the lang and hreflang tag per language, for example { sv: 'sv-SE' } |
cmsLocale |
en |
the CMS's field labels, en or sv; rerun pnpm stomme cms after changing it |
strings |
the built-in text for locale |
your own wording for any interface text, see Strings |
noindex |
none | path prefixes marked noindex, nofollow and left out of the sitemap, such as ['/drafts'] |
metrics.endpoint |
none | an https: URL for first-party metrics, see Measure visits |
analytics.cfToken |
none | a Cloudflare Web Analytics token; the beacon loads on every page, whether or not tracking is on, and without waiting for the consent banner |
maps.provider |
google when maps.key is set |
osm or google, for the findUs map and contactCard's mini-map |
maps.key |
none | a Google Maps key; on an adapter build, map stills are served through /map/<point>.png, so the visitor's browser does not call Google until they click |
contact.endpoint |
none | where the contact form posts, as <endpoint>/contact |
media |
{ storage: 'git' } |
where CMS uploads go, see Store uploads in R2 |
docs |
none | the docs section, see Build docs from a repo |
software |
none | the site presents a software product, see software |
cms |
none | the CMS backend, see cms |
cms
Written into the backend of public/admin/config.yml by stomme cms.
| Key | Default | What it does |
|---|---|---|
backend |
github |
the Sveltia backend: github, gitlab, gitea or forgejo |
repo |
local/<package name> when backend is unset |
owner/name of the site's repository; the placeholder only serves Work with Local Repository |
branch |
main |
the branch the CMS commits to |
baseUrl |
none | an OAuth server for signing in; also where the contact form posts when contact.endpoint is unset |
authEndpoint, apiRoot, gatewayUrl, identityUrl, siteDomain |
none | passed to Sveltia as auth_endpoint, api_root, gateway_url, identity_url and site_domain |
repoPath |
none | the site's folder inside its repository, when the site is not at the repository's root |
Locally, Sveltia's Work with Local Repository reads and writes the folder on disk in Chrome or Edge, and needs the folder you pick to be the repository's root.
software
Set it, even as {}, and the home page adds SoftwareApplication JSON-LD with the site's name and address.
| Key | Default | What it does |
|---|---|---|
name |
the site name | the product's name |
applicationCategory |
none | a schema.org category, such as DeveloperApplication |
operatingSystem |
none | the systems it runs on, such as macOS, Linux |
free |
false |
true adds an offer at price 0 |
repo |
none | the source repository's URL, written as sameAs |
export const site: SiteConfig = {
software: { applicationCategory: 'DeveloperApplication', operatingSystem: 'macOS, Linux', free: true, repo: 'https://github.com/acme/tool' },
};
Strings
strings overrides the interface text one phrase at a time. The groups are readMore, latest, changeLanguage, breadcrumbHome, breadcrumbLabel, listingCta, and the objects contact, beforeAfter, controls, collage, map, footer, documents, sectionNav, subpages, post, town, service, listingStatus, thanks, notFound, consent and docs. Most strings are plain text. These fill in a placeholder:
| Placeholder | Strings |
|---|---|
{name} |
every town string, with the area's name |
{address} |
map.embedTitle, map.embedTitleOsm |
{n} |
collage.more, collage.counter, post.yearCount, post.showingLatest |
{i} |
collage.counter |
{count} |
docs.pages and the docs.cards bodies |
{file}, {ref} |
docs.sourceAt |
town.reasons is a list, not a phrase: { title, body } items shown as a row of cards on every area page, empty by default.
The full English set is SITE_DEFAULTS.strings in @gronare/stomme/config.
export const site: SiteConfig = {
strings: {
readMore: 'Continue reading',
contact: { submit: 'Send', message: 'How can we help?' },
},
};
On a translated site, strings applies to the default language, and the other languages use their built-in text.
features
| Flag | Default | What it turns on |
|---|---|---|
blog |
false |
the posts collection, its post pages and calendar feed, postList, postArchive, eventList; the CMS also offers those three blocks when an article listing exists |
services |
false |
the services collection, service pages, serviceGrid |
areas |
false |
the towns collection, area pages, linkChips, and the areas in the home page's local-business JSON-LD |
testimonials |
false |
the testimonials collection and block |
faq |
false |
the faq collection and block |
documents |
false |
the documents collection and documentList |
tracking |
false |
the tracking settings, marketing tags and the consent banner; the tags and the banner load only once an ID is set in the tracking settings |
docs |
false |
the docs section from site.docs |
pages |
true |
the editable pages; false hides them in the CMS and drops subpages from its block menu |
contactForm |
true |
contactForm and contactSwitch; false leaves them out of every rendered page, while the CMS still offers both blocks |
A site with no features export at all is read two ways. The CMS turns each collection's editor on when its folder exists under src/content/, and the blog's when src/content/posts/ holds a post, while the integration injects no feature routes.
See Turn on a feature. A flag from an outside directory is read the same way.
listings
| Key | Required | What it does |
|---|---|---|
id |
yes | the collection name and its folder src/content/<id>/ |
route |
yes | the index page and the base of entry pages |
label |
yes | the collection's name in the CMS |
preset |
yes | article or catalog |
specs |
no | catalog only: { key, label } fact rows, or bare strings keyed by position |
options |
no | columns, showImages, featured, filters |
See Add a listing.
Integration options
astro.config.mjs calls stomme({ features, routes: site.routes, listings }).
| Option | Default | What it does |
|---|---|---|
features |
none | the feature flags |
routes |
none | the route prefixes |
listings |
none | the listings |
layout |
src/layouts/Base.astro |
the layout injected pages render in |
config |
src/site.config.ts |
the site config file |
locales |
site.locales |
overrides the languages |