ContactFormpopular
apps/www/src/sections/ContactForm.astro · 102 lines · group Dynamic content
ContactForm — the contact form with the site's phone and e-mail beside it: name, e-mail, phone and message fields, a send button, a success message. Use for: the contacts page, or the last section of a landing. Its default id is "contacts", so menu entries and buttons can point at "#contacts" / "/#contacts". Shapes: theme="plain" (default) — a muted panel with the title, phone and e-mail on the left, the fields on the right with their labels as placeholders; theme="panel" — the same inside a raised card, the left part painted with the brand gradient and the fields carrying real labels. Children: none. Where it sends: the form posts to `contactFormReceiverURL` from pages.config.js, protected by Cloudflare Turnstile (`turnstileSiteKey`); with both empty it renders but cannot send. On preview hosts it shows a note instead of sending. Texts: phone and e-mail default to `defaultPhone` / `defaultEmail` of pages.config.js; the labels, the button and the success texts are content — translate them per locale. Ask the user: the two config values are issued by the Gitt One Pages team, who register the receiver (requests land in the site's Telegram group) and the Turnstile pair. Write the tag and its texts; leave `contactFormReceiverURL` and `turnstileSiteKey` as they are and never invent or copy them. When they are empty, end the reply with what the user has to do: ask the team to connect the form, naming the Telegram group that should receive requests, then put the two values into pages.config.js or paste them into the chat. Instructions for people: https://docs.pages.gitt.one/setup/contact-form-and-portfolio/
In the fleet
Used on 4 sites built with this engine.
Samples 2
Talk to someone who has stood in a cold field
Tell us the crop and the field. We answer with a plan, not a quote.
- Phone
- +46 8 123 45 67
MDX of this sample
<ContactForm
title="Talk to someone who has stood in a cold field"
description="Tell us the crop and the field. We answer with a plan, not a quote."
email="hello@nordvind.example"
phone="+46 8 123 45 67"
nameLabel="Full name"
emailLabel="Email"
phoneLabel="Phone"
messageLabel="What are you growing?"
submitText="Send"
successTitle="Thank you!"
successText="We have your message — someone from the team will be in touch shortly."
/>MDX of this sample
<ContactForm
theme="panel"
title="Contact us"
description="Sales, support and the people who build the stations."
email="hello@nordvind.example"
phone="+46 8 123 45 67"
submitText="Send the request"
/>Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| id | string | 'contacts' | anchor of the section (default "contacts") | |
| theme | 'plain' | 'panel' | 'plain' | "plain" muted panel, "panel" raised card with the brand gradient | |
| title | string | yes | the heading beside the form | |
| description | string | a paragraph under the heading | ||
| string | e-mail shown beside the form; defaults to pages.config defaultEmail | |||
| phone | string | phone shown beside the form; defaults to pages.config defaultPhone | ||
| nameLabel | string | 'Full name' | label of the name field | |
| emailLabel | string | 'Email' | label of the e-mail field | |
| phoneLabel | string | 'Phone' | label of the phone field | |
| messageLabel | string | 'Message' | label of the message field | |
| submitText | string | 'Submit' | text of the send button | |
| subject | string | 'Request from Contacts' | subject line of the message the receiver gets | |
| successTitle | string | 'Thank you!' | heading of the message shown after a successful send | |
| successText | string | 'We`ve received your message. Someone from our team will contact you soon' | text under that heading |
Source apps/www/src/sections/ContactForm.astro @ gitt.one
---
/**
* ContactForm — the contact form with the site's phone and e-mail beside it:
* name, e-mail, phone and message fields, a send button, a success message.
*
* Use for: the contacts page, or the last section of a landing. Its default id
* is "contacts", so menu entries and buttons can point at "#contacts" /
* "/#contacts".
* Shapes: theme="plain" (default) — a muted panel with the title, phone and
* e-mail on the left, the fields on the right with their labels as
* placeholders; theme="panel" — the same inside a raised card, the left part
* painted with the brand gradient and the fields carrying real labels.
* Children: none.
* Where it sends: the form posts to `contactFormReceiverURL` from
* pages.config.js, protected by Cloudflare Turnstile (`turnstileSiteKey`);
* with both empty it renders but cannot send. On preview hosts it shows a
* note instead of sending.
* Texts: phone and e-mail default to `defaultPhone` / `defaultEmail` of
* pages.config.js; the labels, the button and the success texts are content
* — translate them per locale.
* Ask the user: the two config values are issued by the Gitt One Pages team,
* who register the receiver (requests land in the site's Telegram group) and
* the Turnstile pair. Write the tag and its texts; leave
* `contactFormReceiverURL` and `turnstileSiteKey` as they are and never
* invent or copy them. When they are empty, end the reply with what the user
* has to do: ask the team to connect the form, naming the Telegram group
* that should receive requests, then put the two values into pages.config.js
* or paste them into the chat. Instructions for people:
* https://docs.pages.gitt.one/setup/contact-form-and-portfolio/
*/
import Envelope from 'astro-heroicons/outline/Envelope.astro';
import Phone from 'astro-heroicons/outline/Phone.astro';
import pagesConfig from '../../pages.config.js';
import Fields from './_ContactFields.astro';
interface Props {
/** anchor of the section (default "contacts") */
id?: string;
/** "plain" muted panel, "panel" raised card with the brand gradient */
theme?: 'plain' | 'panel';
/** the heading beside the form */
title: string;
/** a paragraph under the heading */
description?: string;
/** e-mail shown beside the form; defaults to pages.config defaultEmail */
email?: string;
/** phone shown beside the form; defaults to pages.config defaultPhone */
phone?: string;
/** label of the name field */
nameLabel?: string;
/** label of the e-mail field */
emailLabel?: string;
/** label of the phone field */
phoneLabel?: string;
/** label of the message field */
messageLabel?: string;
/** text of the send button */
submitText?: string;
/** subject line of the message the receiver gets */
subject?: string;
/** heading of the message shown after a successful send */
successTitle?: string;
/** text under that heading */
successText?: string;
}
const {
id = 'contacts', theme = 'plain', title, description, email, phone,
nameLabel = 'Full name', emailLabel = 'Email', phoneLabel = 'Phone', messageLabel = 'Message',
submitText = 'Submit', subject = 'Request from Contacts', successTitle = 'Thank you!',
successText = 'We`ve received your message. Someone from our team will contact you soon',
} = Astro.props;
const contactPhone = phone || pagesConfig.defaultPhone;
const contactEmail = email || pagesConfig.defaultEmail;
const panel = theme === 'panel';
---
<section id={id} class:list={['relative bg-white', panel && 'px-4 py-16 sm:px-6 sm:py-20 lg:px-8']}>
<div class:list={['relative mx-auto max-w-7xl', panel ? 'bg-white shadow-xl lg:grid lg:grid-cols-3' : 'lg:grid lg:grid-cols-5']}>
<div class:list={[panel ? 'relative overflow-hidden bg-gradient-to-b from-primary-500 to-primary-alt-600 px-6 py-10 text-white sm:px-10 xl:p-12' : 'bg-stone-50 px-4 py-12 sm:px-6 lg:col-span-2 lg:px-8 xl:pr-12']}>
<div class="mx-auto max-w-lg">
<h2 class:list={[panel ? 'text-lg font-medium' : 'text-3xl font-extrabold tracking-tight text-stone-900 sm:text-4xl']}>{title}</h2>
{description && <p class:list={['mt-3 text-lg', panel ? 'text-primary-50' : 'text-stone-500']}>{description}</p>}
<dl class:list={['mt-8 space-y-4 text-base', panel ? 'text-white' : 'text-stone-500']}>
{contactPhone && (
<div>
<dt class="sr-only">{phoneLabel}</dt>
<dd class="flex"><Phone class:list={['h-6 w-6 flex-shrink-0', !panel && 'text-stone-400']} aria-hidden="true" /><a class="ml-3" href={`tel:${contactPhone.replace(/[^+\d]/g, '')}`}>{contactPhone}</a></dd>
</div>
)}
<div>
<dt class="sr-only">{emailLabel}</dt>
<dd class="flex"><Envelope class:list={['h-6 w-6 flex-shrink-0', !panel && 'text-stone-400']} aria-hidden="true" /><a class="ml-3" href={`mailto:${contactEmail}`}>{contactEmail}</a></dd>
</div>
</dl>
</div>
</div>
<div class:list={[panel ? 'px-6 py-10 sm:px-10 lg:col-span-2 xl:p-12' : 'bg-white px-4 py-12 sm:px-6 lg:col-span-3 lg:px-8 xl:pl-12']}>
<Fields id={id} labelled={panel} nameLabel={nameLabel} emailLabel={emailLabel} phoneLabel={phoneLabel} messageLabel={messageLabel} submitText={submitText} subject={subject} successTitle={successTitle} successText={successText} />
</div>
</div>
</section>Source links point to engine-astro@7b686388. Samples are demo content: the components are the real ones, the copy and the pictures are made up.