Service areas
Where the business works, as readable text with an optional map.
Installation
npx shadcn@latest add http://localhost:3000/r/service-areas.jsonMKT UI is not published yet, so this points at your local development server. Set NEXT_PUBLIC_REGISTRY_URL to the deployed origin to show the public command.
Also installs: container, section, section-heading.
Usage
import { ServiceAreas } from "@/components/service-areas";
<ServiceAreas
eyebrow="Coverage"
title="Where we work"
areas={[
{ id: "central", region: "Central Austin", locations: ["Hyde Park", "North Loop", "Rosedale"] },
{
id: "surrounding",
region: "Surrounding",
locations: ["Pflugerville", "Round Rock", "Cedar Park"],
note: "Call-out fee applies beyond 20 miles.",
},
]}
note="Just outside these areas? Ask anyway — we can often still help."
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title (required) | ReactNode | — | Section heading. |
| areas (required) | ServiceArea[] | — | Each needs `id`, `region`, and `locations`. |
| map | ReactNode | — | Optional map: an embed, a static image, anything. An enhancement, never the only answer. |
| note | ReactNode | — | Shown under the lists, e.g. what happens just outside the area. |
| action | ReactNode | — | Action under the note. |
| columns | 2 | 3 | 4 | 3 | Columns on wide screens. |
| surface | "default" | "muted" | "brand" | "inverted" | "default" | Background treatment. |
Behaviour
The text is the answer; the map is decoration around it. "Do you cover my area?" is one of the first questions a local visitor has, and the most common way to answer it badly is an embedded map with no text — unusable on a slow connection, invisible to a screen reader, and invisible to search engines looking for the town name.
Each region is a <dl> entry, so the relationship between a region and its towns
survives with styles off.
No map provider is bundled. map is an open slot: pass a static image, an
OpenStreetMap embed, or a paid provider's component. MKT UI does not make that choice
for you and does not require a paid API key.
Limitations
- No map-assisted or radius-based variant.
- No postcode lookup or "check my address" control.
- Long location lists are not columnised within a region.