I’m trying to embed a Google Map in a simple HTML page for a small business site, but the map either doesn’t load at all or only shows a gray box. I’ve copied the iframe code from Google Maps and tried adding the JavaScript API, but I’m clearly missing something. Can someone explain the correct steps or share a working HTML example so the map displays reliably on desktop and mobile?
First thing, separate two different methods. Static iframe embed from Google Maps site, and dynamic JS Maps API. Sounds like you mixed both.
If you only need a simple map, iframe is easiest and does not need an API key.
- Use pure iframe embed
Steps:
- Go to maps.google.com
- Search your business
- Click Share
- Click “Embed a map”
- Copy the iframe code
Example:
Put that directly inside the body tag of your HTML. Do not wrap it in script tags. Do not remove parts of the URL.
Common iframe problems:
- Mixed content. If your site is https, your iframe src must start with https, not http.
- Parent div has zero height. Give the parent a fixed height or use a class like:
.map-container {
width: 100%;
height: 400px;
}
Then:
If the iframe shows a gray box, open the iframe src URL directly in a new tab. If it fails, the URL is broken or got truncated.
- If you want the JS Maps API version
Then you need:
- A Google Cloud project
- Maps JavaScript API enabled
- A valid API key
- Billing enabled on the project
Basic HTML example:
My Map #map { height: 400px; width: 100%; } body, html { margin: 0; padding: 0; }<script>
function initMap() {
const myLocation = { lat: 40.7128, lng: -74.0060 };
const map = new google.maps.Map(document.getElementById('map'), {
center: myLocation,
zoom: 14,
});
new google.maps.Marker({
position: myLocation,
map: map,
});
}
</script>
<script
src='https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap'
async
defer>
</script>
Common JS problems that give a gray box:
- Missing height on the map div. If #map has no height, you see nothing.
- Wrong or missing API key. Check browser console for errors like “ApiNotActivatedMapError” or “InvalidKeyMapError”.
- Using callback=initMap in the script URL but your function name is different or has a typo.
- Ad blockers or strict content blockers. Test in incognito with extensions off.
Quick checklist for your case:
- If you use iframe, remove any google maps JS script. Keep iframe only.
- Make sure src is full https URL copied from Google, unedited.
- Give the iframe or its container a clear height.
- If you use JS API, check:
- div id matches the one in getElementById
- style has a height
- API key exists, billing is on, API enabled
- No console errors in DevTools
If you paste your current HTML (strip your API key), people can point at the exact line that breaks it.
Sounds like the gray box is coming from how it’s being placed in the page rather than from Google itself, especially if you mixed the iframe and JS API like you mentioned.
I agree with @sterrenkijker on splitting iframe vs JS API, but I’d look at a few other angles they didn’t focus on as much:
1. Pick one method in your actual code
If your HTML looks something like:
<div id='map'></div>
<iframe src='...maps/embed?pb=...' ...></iframe>
<script src='https://maps.googleapis.com/maps/api/js?key=...&callback=initMap'></script>
<script>
function initMap() { ... }
</script>
you’re kind of telling the browser, “Put a map here, and also put a different map here, and also run a script that expects an empty div named map.” That usually leads to a mess or a gray box.
Decide:
- Only iframe: delete all
<script src='https://maps.googleapis.com/...'>tags and anyinitMapcode. - Only JS API: delete the
<iframe>completely.
Having both is not “more map,” it’s just more things to break.
2. Check where you placed the code
I’ve seen this a lot:
<head>
...
<iframe src='https://www.google.com/maps/embed?pb=...' ...></iframe>
</head>
<body>
...
</body>
An iframe in <head> is invalid and often just renders as nothing or ugly gray. Make sure the map is inside <body> only.
Same if you did something like:
<script>
<iframe src='...'></iframe>
</script>
No, that’s not valid. The iframe is HTML, not JavaScript. It should be raw in the HTML, not inside a script tag.
3. Check CSS that might hide it
Sometimes the iframe is actually loading fine, but your own CSS kills it.
Watch for things like:
iframe {
display: none;
}
/* or */
#map iframe {
height: 0;
}
/* or some global reset: */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
The last one is fine, but combined with “no explicit height on parent containers,” it can collapse everything.
Quick test:
<iframe
src='YOUR_EMBED_URL_HERE'
width='600'
height='450'
style='border: 1px solid red;'
></iframe>
Drop that directly into a bare test file like this:
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<title>Map test</title>
</head>
<body>
<iframe
src='YOUR_EMBED_URL_HERE'
width='600'
height='450'
style='border:1px solid red;'
loading='lazy'
referrerpolicy='no-referrer-when-downgrade'>
</iframe>
</body>
</html>
Open that file by itself.
If it works here but not in your real page, then your CSS or layout is the problem, not Google.
4. Check the browser console & network
People skip this but it’s super helpful:
- Open DevTools (F12).
- Go to Console.
- Reload the page.
Look for:
- Content Security Policy errors like “Refused to frame ‘https://www.google.com’.”
That means your server or hosting is blocking iframes from Google. - Mixed content like “blocked because it is insecure.”
That happens if:- Page is
https:// - Map iframe (or JS) is
http://or protocol-relative and your host is weird.
- Page is
Also, the Network tab: filter by “maps” or “google” and see if any red requests fail.
5. If you’re using the JS API, double check key & restrictions
Since you said you “tried adding the JavaScript,” quick silent killer is API key restrictions:
- If the key is locked to
example.comand you’re testing onlocalhost:3000, it fails. - If you restricted it to “Maps JavaScript API” and didn’t actually enable that API in Cloud Console, same deal.
Console will show errors like:
Google Maps JavaScript API error: RefererNotAllowedMapErrorGoogle Maps JavaScript API error: ApiNotActivatedMapError
Those always explain exactly what’s wrong; it’s just easy to ignore the red text.
6. Host-level or builder issues
If this is inside:
- A page builder (Wix, Squarespace, etc.).
- A CMS with an editor that “cleans” HTML.
They might:
- Strip out
iframetags. - Strip attributes like
srcorallowfullscreen.
View the final source in the browser (Ctrl+U) and confirm that the iframe you think you added is actually there, with a valid src. Sometimes you paste the map code in the editor, save, and the platform silently mangles it.
7. Quick sanity checklist
For iframe route:
- Map code is only an iframe, no Google JS scripts.
- It lives inside
<body>, not<head>or inside<script>. - The iframe has an explicit width/height and is not inside a
height: 0ordisplay: nonecontainer. - The
srcstarts withhttps://www.google.com/maps/embed?pb=...and was not shortened or edited. - No CSP or X-Frame-Options header on your server blocking it.
For JS API route:
- No iframe. Just a
<div id='map'></div>. - That
divhas a fixed height in CSS. - Script URL includes
key=YOUR_KEY&callback=initMap. initMapexists and the name matches exactly.- API key validity and restrictions checked in the console errors.
If you post the exact HTML structure you’re using (with the key removed if there is one), we can probably point to the single line that’s causing the gray box. Nine times out of ten it’s either: “iframe inside <head>” or “zero height container,” not anything fancy with Google itself.
Short version: your gray box almost always comes from either layout/CSS, security headers, or mixing features, not from the embed code itself.
@chasseurdetoiles and @sterrenkijker already nailed the “pick iframe vs JS API” decision and showed clean examples, so I’ll skip repeating that and look at things they only touched lightly.
1. Treat the map as just another block element
People often give the iframe perfect code but then wrap it in a flex/grid layout that collapses it.
Common culprits:
.container {
display: flex;
align-items: stretch;
}
.map-wrapper {
flex: 0 0 auto; /* or sometimes flex: 0 1 auto with no height */
}
If your map is inside an element with no natural height and no explicit height, it can shrink to zero and you see gray.
Quick experiment: temporarily move the iframe (or #map div for JS) to the very top of <body>, outside all layout containers, and give it a hard height:
<div style='height:400px;border:1px solid red;'>
<!-- iframe OR JS map div goes here -->
</div>
If it suddenly works, your layout is the problem.
2. If you are using JS API, avoid inline height: 100% at first
I slightly disagree with the idea of immediately using height: 100% on the map container. If you are still debugging, 100% depends on all parents having heights, which is exactly what often fails.
Instead, hardcode something like:
#map {
height: 400px;
width: 100%;
}
Once it works, then refactor to percentage‑based heights if you really want a full‑screen map.
3. Check your hosting / headers
Two less obvious issues that can cause gray or empty maps:
-
Content Security Policy
If your host or framework sets a strict CSP without
frame-srcorscript-srcallowing Google, the browser will silently block the map. Console usually shows:Refused to load the script because it violates the Content Security Policy
or
Refused to frame because it violates the Content Security Policy
For iframe approach,
frame-src(orchild-srcin older setups) needs to includehttps://www.google.comandhttps://maps.googleapis.com.
For JS API,script-srcmust allowhttps://maps.googleapis.com. -
X-Frame-Options or frame-ancestors
If you are trying to embed a map inside another app that sets
X-Frame-Options: DENYor a strictframe-ancestorsCSP, that can also interfere. Open DevTools → Network, click the response for your page or iframe, and inspect headers.
4. Watch out for HTML sanitizers and builders
Page builders, some CMS editors, and even some security plugins will:
- Strip
<iframe>entirely. - Remove certain attributes.
- Replace your embed code with a “safe” placeholder, which looks like a gray box.
You can verify this by:
- Viewing the actual page source in the browser after publish.
- Making sure your iframe code appears exactly as you pasted it.
If your editor keeps stripping it, sometimes you need a “code block” / “raw HTML” widget rather than a rich text field.
5. Ad blockers and script blockers
This is underestimated. Some privacy extensions block map scripts or iframes coming from Google domains:
- Test in a private window with all extensions disabled.
- Test in another browser.
If it works there, the code is fine; you just need to accept that a fraction of users with aggressive blockers may not see the map at all, regardless of what you do.
6. For JS API specifically, validate key restrictions
Building on what @chasseurdetoiles said about keys, another subtle problem is domain matching:
- If the key is restricted to
mybusiness.combut you are testing attest.mybusiness.comorlocalhost, it fails. - If you are on
httpsbut your restriction pattern is only forhttp, that can also fail.
Make sure the referrer restrictions include exactly how you are loading the page, including protocol and subdomain, usually via wildcards like:
https://mybusiness.com/*https://*.mybusiness.com/*http://localhost/*while developing
The console messages from the Maps JS API are usually clear, so do not ignore them.
7. About the “product title” as a generic note
Since you mentioned the product title ``, quick pros and cons in this context:
Pros:
- Can help organize your HTML snippets or templates so your map embed is isolated and easier to debug.
- Makes your markup more readable if you wrap the map in a consistently named structure, which indirectly improves SEO by keeping your layout clean and predictable.
Cons:
- Does not fix API key, CSP, or mixed‑content issues by itself.
- If overused or misconfigured, can add another layer of abstraction where you forget what is actually in the page, which makes debugging things like the gray map box harder.
It is useful for readability and maintainability, but not a magic fix for Maps issues.
8. How to narrow your exact problem
If you want to pinpoint this without guessing:
- Create a new bare HTML file on your machine with only the minimal map example (either pure iframe or the tiny JS API sample).
- Open it directly in the browser from disk.
- If it fails already, your embed code or key is wrong.
- If it works locally but not on your live site:
- Compare page source.
- Check CSP and other headers.
- Check layout differences.
That “A/B” between a bare file and your real site is often the quickest way to locate the exact cause of the gray box.
Both @sterrenkijker and @chasseurdetoiles covered the standard path correctly. Your next step is to do that isolated test file and then inspect CSP / layout on the real site. Once you paste your current layout (with any API key removed) it should be possible to point to the precise element or rule causing the map not to render.