Contact, Booking & Contact Dock
Files: src/content/contact/<language>/-index.md, src/content/sections/<language>/contact-section.md, src/config/config.toml ([settings.contactInfo], [settings.contactDock]) · Skill level: Beginner
Margo gives visitors three ways to reach you: the contact form on /contact/, “Book a call” buttons that go to your scheduling page, and an optional contact dock at the bottom of the screen. The form’s fields and where it sends messages are on Forms.
The Contact Page
/contact/ shows the page header, the contact section, and a few questions (the FAQ section). It has no call to action above the footer. Its file is src/content/contact/<language>/-index.md:
pageHeader: title: "Tell me about your *project*" description: "**Start with a few lines.** The brand, the timing, and a rough budget are enough." image: "/images/people/persona-designer-alt.jpg" # the portrait in the `split` layout imageAlt: "Portrait of Hugo Merrin" options: layout: "split" # centered | left | split
contactSection: options: layout: "booking" # form | booking
faqSection: items: - question: "How soon will I hear back?" answer: "Within a day on weekdays..." options: layout: "single"The contact page file has no schema, so npm run astro-check doesn’t report a mistyped option there. Open /contact/ after each change.
The Contact Section
The default copy is in src/content/sections/<language>/contact-section.md: the heading (title), the line under it (description), the form, and what sits beside the form. Both layouts show the same form on the left.
| Layout | Beside the form | Fields it reads |
|---|---|---|
form | Ruled rows with your contact details, then a row of social icons | details, social |
booking | A card with your availability, a short heading, a checklist, and a “Book a call” button | card |
Contact details (form layout):
details: - label: "Email" copy: true # adds a "Copy email" button - label: "Phone" value: "+1 (555) 010-0199" url: "tel:+15550100199" - label: "Studio" value: "Lisbon, Portugal" # no url: plain textsocial: label: "Elsewhere" items: - label: "Instagram" icon: "/images/icons/social/instagram.svg" # an SVG drawn in the text color, or a Lucide name url: "https://www.instagram.com/"An empty social.items list hides the row.
The booking card (booking layout):
card: enable: true availability: enable: true label: "Open for new projects" title: "Prefer a conversation?\nPick a *time* that works." items: - "A short video call, no slides and no preparation" button: enable: true label: "Book a call" url: "" # empty: your booking link from config.tomlThese rows can differ per language, so change them in every language folder. A contactSection: block in a page file that has a schema (such as src/content/pages/ or about-us/) must include title, description, and form.
Your Booking Link And Email
Set them once in config.toml:
[settings.contactInfo] booking = "/contact/" # your scheduling page URL, or a page of your sitebooking is where the “Book a call” buttons go when their own url is empty: the booking card on /contact/, the FAQ booking card, the call to action, the service pages, and the contact dock. Put the full https:// address of your scheduling page here, from any scheduling service. While it is /contact/, those buttons send visitors to the contact form, and the button on the contact page points at the page itself.
email feeds the “Copy email” button of the contact dock. phone, address, and officeHours are in the same table, but the theme’s layouts don’t show them. Keep them for your own components, or leave them as they are. The details beside the form come from contact-section.md, not from this table.
The Contact Dock
A small bar at the bottom center of the screen with an availability line and two buttons: Copy email and Book a call. It slides in once the first section of the page has scrolled away, and hides while the footer is in view. It is off by default.
[settings.contactDock] enable = false # true shows it on every page showAfter = "first-section"To show or hide it on one page only, add contactDock: true or contactDock: false to that page’s frontmatter. The buttons use email and booking from [settings.contactInfo]; with neither set, the dock doesn’t show. Its labels are under dock in src/i18n/<language>.json, in every language.
The dock stays hidden while the cookie banner is open, and it needs JavaScript; the footer carries the same contact links for everyone. When the dock is on, the back-to-top button is not shown.
Do It With AI
Set up my contact page. My scheduling link is [URL] and my email is [EMAIL]: set booking and emailin [settings.contactInfo] of src/config/config.toml. Insrc/content/sections/english/contact-section.md, set the details rows to [EMAIL, PHONE, CITY]and the social items to [LINKS], and use the [form | booking] layout. Make the same changes inthe french and arabic files, translating the labels. [Turn on the contact dock in[settings.contactDock].] Then open /contact/ and check it.