Google Maps Embed React component
A Google Maps embed for one or more locations, with no API key needed: a hairline location list that crossfades the map, map/satellite and zoom controls, a darkened map for dark themes, directions and copy-address actions, live local time and an optional click-to-load consent screen.
About the Google Maps Embed component
Google Maps Embed puts a live Google map next to the places you want people to find: a list of locations on the side, the map on the right, and the actions visitors actually need, like directions, opening the place in Google Maps, copying the address and calling. It works without an API key, so you can drop it in and see a real map straight away.
Picking another location keeps the current map on screen until the next one has loaded and then fades it in, so there's no white flash. Map/satellite and zoom controls sit in a readout bar under the map, out of the way of Google's own controls, and the dark theme darkens the map itself to match.
When to use it
Use it on a contact page, a store locator with a few branches, an event venue page or the footer of a local business site, anywhere a visitor's next step is getting there.
For dozens of pins, clustering or custom markers, use the Google Maps JavaScript API or a library like MapLibre instead; an embed shows one place at a time.
Installation
Add the Google Maps Embed component to your project with the shadcn CLI. It lands in components/google-maps-embed.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add @reactframe/google-maps-embedOr copy the source by hand and install its dependencies:
npm install lucide-react clsx tailwind-mergeProps
<GoogleMapsEmbed /> accepts 17 props, all optional. It also accepts the usual <section> attributes, like className, style, id and aria-*, and passes them to its root element.
| Prop | Type | Default |
|---|---|---|
| locations | MapLocation[] | LOCATIONS |
| defaultLocationId | string | — |
| eyebrow | string | "Visit us" |
| title | string | "Find our studios" |
| description | string | "Three rooms, one practice. Drop by for a coffee or book a walkthrough of the workshop." |
| apiKey Google Maps Embed API key. Without one the keyless embed URL is used, which needs no setup. | string | — |
| zoom | number | 15 |
| mapType | "roadmap" | "satellite" | "roadmap" |
| mapTone "auto" darkens the map in the dark theme. "muted" is greyscale. Satellite is never filtered. | "auto" | "default" | "dark" | "muted" | "auto" |
| language Language for map labels, e.g. "en", "tr", "de". | string | "en" |
| requireConsent Show a placeholder until the visitor agrees to load Google Maps (GDPR-friendly). | boolean | false |
| height Map height in px on wide layouts. | number | 480 |
- locationsMapLocation[]Default: LOCATIONS
- defaultLocationIdstring
- eyebrowstringDefault: "Visit us"
- titlestringDefault: "Find our studios"
- descriptionstringDefault: "Three rooms, one practice. Drop by for a coffee or book a walkthrough of the workshop."
- apiKey
Google Maps Embed API key. Without one the keyless embed URL is used, which needs no setup.
string - zoomnumberDefault: 15
- mapType"roadmap" | "satellite"Default: "roadmap"
- mapTone
"auto" darkens the map in the dark theme. "muted" is greyscale. Satellite is never filtered.
"auto" | "default" | "dark" | "muted"Default: "auto" - language
Language for map labels, e.g. "en", "tr", "de".
stringDefault: "en" - requireConsent
Show a placeholder until the visitor agrees to load Google Maps (GDPR-friendly).
booleanDefault: false - height
Map height in px on wide layouts.
numberDefault: 480
Show all 17 propsShow fewer
| showControls | boolean | true |
| showActions | boolean | true |
| theme | "dark" | "light" | "dark" |
| radius | number | 12 |
| onLocationChange | (location: MapLocation) => void | — |
- showControlsbooleanDefault: true
- showActionsbooleanDefault: true
- theme"dark" | "light"Default: "dark"
- radiusnumberDefault: 12
- onLocationChange(location: MapLocation) => void
npm dependencies
Installed for you by the shadcn CLI.
Google Maps Embed FAQ
- Do I need a Google Maps API key?
- No. Without apiKey it uses Google's keyless embed URL, which needs no account or billing. Pass apiKey to switch to the official Maps Embed API, which Google recommends for production and which is free for embeds.
- What should I put in a location?
- A name and an address are enough; the address is what Google searches for. Add lat and lng to pin an exact spot and show coordinates in the readout, or query to search for something else, such as the business name as it appears on Google.
- How does the dark map work?
- Google's embed can't be styled, so in the dark theme the roadmap gets a CSS invert and hue-rotate filter. Set mapTone to default to turn it off, or muted for a greyscale map. Satellite view is never filtered.
- Is it GDPR friendly?
- Set requireConsent and nothing loads from Google until the visitor presses Load map. Until then they see a short note and an Open in Google Maps link.
- Why does the zoom stepper reload the map?
- The embed has no zoom API, so changing zoom changes the map URL. The old map stays up until the new one is ready, so it reads as a crossfade. Visitors can still pinch, scroll and drag inside the map.