build69
build69  /  Components  /  Marketing Sections  /  Contact

Contact

v1.0.19Updated 19 Oct 2026

Contact section pairing a message form with details / map. Copy-paste block; baked-in demo content (edit the JSX to customise).

Preview

Live · 12 stories
▸Why this is recommendedcontactformmapget-in-touch+3

Contact in a two-column split layout.

Recommended for+14
  • ✓Contact pages
  • ✓Landing pages
  • ✓Marketing pages
Tags+6
contactformmapget-in-touchmarketingsectionsplit
Features+4
  • Split (form + info), centered and with-map layouts
  • Name / email / message fields
  • Configured entirely by props, never by editing the vendored file: contactInfo (rows), social (accounts), departments (routing cards), channels (quick-contact tiles), faqs, mapHref
  • Contact details have NO default: with nothing passed a block renders its heading, eyebrow and subcopy plus a short empty note from labels, rather than our mailbox, phone number, Bangkok address, four example.com departments and a LINE handle (condo69 fb_bc8045e2 / fb_f8fba1de)
  • No dead controls: both href-hash anchors are gone - a social icon renders only with a destination, a channel tile without one renders inert and loses the hover-lift, and a department card without one shows its address as text
  • A real submit: onSubmit(values) is awaited (pending, then success only on resolve, then an error line on reject), or pass action/method for a no-JavaScript POST. With neither, the submit button renders disabled; the setTimeout fake that announced success is deleted
  • ContactDark runs the same form as the light blocks instead of a second copy whose submit did nothing
  • Client-side routing: pass linkComponent and every anchor routes through the host app link component instead of a plain anchor (fb_bf7dc63a)
Not recommended for−2
  • ✕In-app support widgets

Install

Ask your agent, or call the MCP tool directly. The resolved bundle is written into your project.

get_registry_item({ name: "Contact" })

Usage

import { ContactSplit } from '@/components/sections/contact';

<ContactSplit />

Tick variants in the left menu — each adds a tab with that variant’s real story source, the same code the preview above renders.

Props

PropTypeRequired
className

Optional wrapper class override

string—
labels

Override every built-in display string across the contact family (headings, subcopy, field labels and placeholders, department and channel chrome, submit button, map alt text, aria-labels) for i18n or white-labelling. Merged over DEFAULT_CONTACT_LABELS.

Partial<ContactLabels>—
contactInfo

Your own contact details (email, phone, address, opening hours) for ContactSplit / ContactCentered / ContactWithMap / ContactCardCentered / ContactDark / ContactSplitGradient. Empty by default: a block with none keeps its heading, eyebrow and subcopy and shows labels.infoEmpty instead of a mailbox and street address of ours. Each item carries its own optional href (mailto:, tel: or a path); an item with no href renders as plain text, never as a dead anchor. MCP feedback fb_bc8045e2 / fb_f8fba1de.

ContactInfoItem[]—
social

The ContactSplit follow-along row (brand key or your own icon node). Empty by default; an account with no href is not rendered at all, and the row AND its heading disappear when there are none. It used to be four icons hardwired to a dead anchor.

ContactSocialLink[]—
departments

The ContactDepartments routing cards. Empty by default (labels.departmentsEmpty). A card with no href shows its address as plain text and drops the clickable hover-lift; the four example.com mailboxes are gone.

ContactDepartment[]—
channels

The ContactWithChannels quick-contact tiles (LINE, email, phone). Empty by default (labels.channelsEmpty). A tile with no href renders as a non-interactive element without the hover-lift instead of a dead anchor.

ContactChannel[]—
faqs

The ContactWithFaqStrip question and answer pairs; the first is open. Empty by default (labels.faqEmpty).

ContactFaqItem[]—
mapHref

Where the map placeholder goes (a maps URL or your directions page) in ContactWithMap / ContactWithMapPlaceholder. Without it the map stays a labelled role=img graphic rather than a card that looks tappable and goes nowhere.

string—
onSubmit

Send the message: (values: ContactFormValues) => void | Promise<void>. Awaited - the button shows its pending state while the promise is in flight, labels.successMessage appears ONLY after it resolves, and a rejection shows labels.errorMessage. The form used to fake a 900ms setTimeout round-trip and then claim success.

ContactSubmitHandler—
action

Plain form POST target for hosts with no JavaScript submit path; forwarded to the form element. With neither action nor onSubmit the submit button renders disabled.

string—
method

The form method used with action. Defaults to post.

"get" | "post"—
linkComponent

The host app link component (next/link, React Router Link) for EVERY anchor these blocks render - contact rows, map link, department cards, channel tiles, social icons. Defaults to a plain anchor, which in a routed app reloads the whole document. MCP feedback fb_bf7dc63a.

ContactLinkComponent—

Related