Config Reference
File: src/config/config.toml · Skill level: Beginner
config.toml holds every site-wide setting: your site name and address, search engine settings, the header and footer layouts, the forms, the animations, 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 Margo ships.
Values marked PLACEHOLDER in the file must be replaced before you launch.
Site Identity
Table: [site]
| Key | Ships as | What it does |
|---|---|---|
title | "Margo" | Site name. The wordmark when logoText and logo are empty, {brand} in the footer copyright, the site name in social previews and structured data, and the RSS feed title |
description | a sentence about the theme | Default description for search results and social previews. A language with site.description set in src/i18n/<lang>.json uses that instead |
tagline | "Creative Portfolio Astro & Tailwind CSS Theme" | Added to every page title (“About - your tagline”) and social titles. Keep it under about 55 characters. A language with site.tagline set in src/i18n/<lang>.json uses that instead (French and Arabic do). 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 (SVG or PNG). Empty shows logoText as a text wordmark |
logoText | "Margo" | The wordmark text. With a logo image it shows next to it; empty shows the image only |
logoWidth, logoHeight | "24px", "36px" | Logo image size. Used only when logo is set |
trailingSlash | true | URLs end with / (/about/). 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.
Search Engines
Tables: [seo], [seo.identity], [seo.robotsTxt], [seo.ai], [seo.sitemap]
| Key | Ships as | What it does |
|---|---|---|
author | "Getastrothemes" | Default author meta tag. Put your own name or studio here |
keywords | eight portfolio keywords | Default keywords for pages without their own keywords |
robots | "index, follow, max-snippet:-1, ..." | Default robots meta tag. Lets search and AI answers quote pages and show images in full |
[seo.identity] type | "Organization" | Organization for a studio or business, Person for one named designer or photographer. Used in the structured data on every page |
[seo.identity] name | "" | Who runs the site. Empty uses [site] title |
[seo.identity] jobTitle | "" | Person only, for example "Brand designer" |
[seo.identity] image | "" | A logo for an organization or a photo for a person. Empty uses [site] logo, else the built-in mark |
[seo.robotsTxt] enable | true | Builds /robots.txt |
[seo.robotsTxt] disallow | [] | Paths crawlers must skip |
[seo.robotsTxt] aiSearch | true | false asks AI answer engines (ChatGPT search, Claude, Perplexity, and others) not to fetch your pages |
[seo.robotsTxt] aiTraining | true | false asks crawlers that collect content to train AI models to stay away |
[seo.ai] llmsTxt | true | Builds /llms.txt and /llms-full.txt, one per language |
[seo.ai] markdownPages | true | A Markdown copy of each project, service, journal post, team member, legal page, and the pricing and FAQ pages at <page>.md |
[seo.ai] indexNowKey | "" | An 8 to 128 character key turns on IndexNow; run npm run indexnow after each deploy |
[seo.sitemap] enable | true | Builds the sitemap |
[seo.sitemap] exclude | [] | Folder names to leave out of the sitemap |
Details: SEO & AI Visibility and AI Links & llms Files.
General Settings
Table: [settings]
| Key | Ships as | What it does |
|---|---|---|
blogFolder | "blog" | Folder name of the journal. 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 |
projectsFolder | "projects" | The same, for projects (case studies and photo series) |
blogPagination | 6 | Posts per journal list page |
pagination | 8 | Used for the journal only when blogPagination is empty |
stickyHeader | true | Kept for older themes. Margo’s header always stays at the top of the screen, so this key changes nothing |
colorMode | "light" | Light or dark mode on a visitor’s first visit: light, dark, or system (follows the device). See Colors & Fonts |
contactFormAction | "https://formsubmit.co/[email protected]" | Placeholder. Where the contact form sends its data. npm run dev and build warn until you change it |
contactFormProvider | "formsubmit.co" | "formsubmit.co", "formspree", or "netlify" |
Details: Forms.
Header, Footer, And Page Background
Table: [settings.layout]
| Key | Ships as | What it does |
|---|---|---|
header | "bar" | pill, bar, or overlay |
footer | "email" | wordmark, columns, or email |
frame | true | Thin ruled lines at the edges of the content and at the top of sections. false removes them |
aurora | true | Soft color fields behind every page. false leaves a plain background |
A page’s headerLayout or footerLayout frontmatter wins over header and footer. See Header, Footer, and Colors & Fonts.
Search
Table: [settings.search]
| Key | Ships as | What it does |
|---|---|---|
enable | true | The site search window (Cmd + K, Ctrl + K, or /) |
exclude | ["/components/"] | Address prefixes left out of the search index |
The index is built at the end of npm run build, so search works on the built site, not in npm run dev. Details: Search.
Smooth Scroll
Table: [settings.smoothScroll]
Smooth scrolling for mouse and trackpad, powered by Lenis. Touch screens keep their normal scrolling.
| Key | Ships as | What it does |
|---|---|---|
enable | true | false gives you the browser’s normal scrolling |
respectReducedMotion | true | Keeps it off for visitors who ask for less motion |
duration | 1.0 | How long the glide lasts. Higher feels slower |
easing | "expo" | expo, linear, easeOutQuad, or easeOutCubic |
smoothWheel | true | Smooths mouse wheel and trackpad scrolling |
syncTouch | false | Smooths touch input on devices with a mouse and a touchscreen |
wheelMultiplier | 1 | How far one wheel movement scrolls |
touchMultiplier | 1 | How far one swipe scrolls when syncTouch is on |
anchors | true | Glides to #section links, offset by the header height |
autoRaf | false | No effect: the theme always drives Lenis from its own animation loop |
stopInertiaOnNavigate | true | Stops any remaining glide when a visitor clicks a link |
Details: Smooth Scroll.
Cookie Banner
Table: [settings.cookieConsent]
| Key | Ships as | What it does |
|---|---|---|
enable | true | Shows the cookie banner and holds data-consent scripts until visitors choose |
revision | 1 | Raise 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 each other language folder). 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.
Theme Credit
Table: [settings.themeCredit]
The theme credit, editable in config.toml. It is one small line in every footer layout and the last line of llms.txt. The part of text in [brackets] becomes the link to url.
[settings.themeCredit] enable = true text = "Built on the Margo Astro theme by [Getastrothemes]" url = "https://getastrothemes.com/astro-themes/margo/"Page Actions And AI Links
Table: [settings.pageActions]
| Key | Ships as | What it does |
|---|---|---|
enable | true | The Copy page menu at the end of each journal post: copy the post as Markdown, open the Markdown copy, or ask an assistant about it. Copy and View as Markdown need [seo.ai] markdownPages |
footer | true | A row at the bottom of every footer layout with Ask AI links, the page in Markdown, llms.txt, and llms-full.txt |
providers | ["chatgpt", "claude", "perplexity", "grok"] | Assistants offered in “Ask”. Empty hides the “Ask” links |
Animations
Table: [settings.animation]
With enable = false, or for visitors who ask for less motion, every page is static and fully visible.
| Key | Ships as | What it does |
|---|---|---|
enable | true | Turns every animation on or off |
respectReducedMotion | true | Shows content without animation for visitors who ask for less motion |
intro | true | The hero and page header headline animate in when the page opens |
reveal | true | Content fades and rises in on scroll, headings blur in word by word, numbers count up |
scroll | true | Effects tied to scrolling: parallax, text and images that move with the scroll, the hero card flight |
webgl | true | Animated backgrounds on the surfaces that ask for one (options.webgl). false keeps the still dots |
mobile | "lite" | Below 768 px: full, lite (reveals, counters, and moving rows, no scroll effects), or off |
pageTransitions | true | A fade between pages, and the project image moving into the project page (Chrome, Safari 18.2 and later) |
easing | "expo" | expo, quart, cubic, or any CSS timing function |
duration | 0.9 | Reveal duration, in seconds |
stagger | 0.08 | Delay between items of a group, in seconds |
distance | "1.25rem" | How far content rises while fading in |
rootMargin, threshold | "0px 0px -10% 0px", 0.15 | How early an element starts animating |
Details: Animations.
Pointer Label, Contact Dock, And Edge Blur
Tables: [settings.cursor], [settings.contactDock], [settings.edgeBlur]
| Key | Ships as | What it does |
|---|---|---|
[settings.cursor] enable | true | A small “View” or “Read” label follows the pointer over project and journal cards (mouse and trackpad only) |
[settings.contactDock] enable | false | A small bar at the bottom of the screen with an availability line, Copy email, and Book a call. A page turns it on or off with contactDock: true or false in its frontmatter |
[settings.contactDock] showAfter | "first-section" | The dock slides in once the first section of the page has scrolled away |
[settings.edgeBlur] enable | false | A soft blur along the bottom edge of the screen, on large screens with a mouse. Check that pages still scroll smoothly on a slower computer if you turn it on |
The dock’s email and booking link come from [settings.contactInfo]. Details: Animations and Contact & Booking.
Layout Switcher
Table: [settings.layoutSwitcher]
Keep enable = false on your own site. To change how a section looks, set options.layout: see Section Layouts.
Copyright
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 journal and by the columns footer.
| Key | Ships as | What it does |
|---|---|---|
enable | true | false hides every signup form |
title | "" | Empty uses subscription.title from the i18n files |
note | "" | The line under the field. Empty uses subscription.note |
formAction | a placeholder URL | Placeholder. Your Mailchimp embedded form action. Change each & 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]
| Key | Ships as | What it does |
|---|---|---|
enable | true | false builds only the default language. Then run npm run remove-multilingual to delete the files of every other language |
defaultLanguage | "en" | Language served without a prefix |
disableLanguages | [""] | Languages to skip, for example ["ar"] |
showDefaultLangInUrl | false | true adds the prefix to the default language too (/en/about/) |
Restart the dev server after any change here. Details: Internationalization.
Contact Details
Table: [settings.contactInfo]
| Key | Ships as | What it does |
|---|---|---|
email | "[[email protected]](mailto:[email protected])" | Placeholder. Used by the Copy email buttons of the contact dock and the mobile menu, and listed in llms.txt |
booking | "/contact/" | Where every Book a call button goes: the contact dock, the FAQ card, the call to action, and the booking card on the contact page. Use your scheduling page (a full https:// address) or a page of your site |
phone | a sample number | Listed in llms.txt. Not shown on the pages |
address | a sample address | Listed in llms.txt. Not shown on the pages |
officeHours | sample hours | Not shown by the theme’s layouts |
The email, phone, location, and social rows beside the contact form are in src/content/sections/<language>/contact-section.md, so they can differ per language. See Contact & Booking.
Header Button
Table: [settings.navigationButton]
| Key | Ships as | What it does |
|---|---|---|
enable | true | Shows the button at the end of the header and in the mobile menu |
label | "" | Empty uses nav.letsTalk from the i18n files (“Let’s talk”). A value here is used in every language |
url | "/contact/" | Where it goes |
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) ordark(dark code blocks in both modes), for fenced code in Markdown and MDX.[settings.markup.tableOfContents]: the “On this page” list on journal posts and text pages such as the privacy policy. It ships withenable = true,expanded = false,startLevel = 1,endLevel = 5, andordered = false.
Social Previews
Table: [opengraph]
| Key | Ships as | What 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 |
generateImages | true | During npm run build, draws a 1200×630 card 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/
| File | What it holds | Page |
|---|---|---|
menu.<language>.json | The header menu (headerPrimary) and the footer link columns (footer) | Menus |
language.json | The languages: name, code, content folder, direction, ogLocale, dateLocale, and order | Internationalization |
fonts.json | The fonts: text, the serif accent, and Arabic | Colors & Fonts |
social.json | Social links and their icons (main list) | Footer |
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"PLACEHOLDER" or still using example.com, and the current value of each. Don't change anythingyet.