My embedded Google Map suddenly stopped displaying correctly on my website after I updated some layout and script files. I need help figuring out if it’s an API key issue, a permissions setting, or something wrong with my embed code so the map will load and be fully interactive again.
First thing I would do is figure out if the problem is the API key or something you changed in layout/scripts.
Quick checklist:
-
Open browser console
- Chrome: F12 → Console
- Look for Google Maps errors like:
- “Google Maps JavaScript API error: ApiNotActivatedMapError”
- “InvalidKeyMapError”
- “RefererNotAllowedMapError”
Those messages point straight to the cause.
-
Check your API key
- Go to Google Cloud Console → APIs & Services → Credentials.
- Make sure the key in your script tag matches exactly.
- Confirm there is no extra space, no old key cached in your code.
- If you added HTTP referrer restrictions, confirm your site domain matches, including protocol and subdomain.
Example:- Your site is https://www.example.com
- Allowed referrer must be something like https://www.example.com/*
- If you changed from http to https or moved to a subdomain, update the restrictions.
-
Confirm required APIs are enabled
- In Google Cloud Console → APIs & Services → Library.
- Enable:
- Maps JavaScript API
- Geocoding API if you use addresses
- Places API if you use autocomplete or place details
- If you see “Billing has been disabled for this project” in console, you need to fix billing.
-
Check billing and quotas
- Go to Billing → check the account linked to your project.
- Make sure the project is attached to an active billing account.
- If you get an error about “billing not enabled” in console, that is the issue.
-
Verify how you embed the map
Two main cases:a) Simple iframe embed from Google Maps
- Example:
- If you use this, no API key needed.
- If this broke after layout changes, inspect the iframe container:
- Check width and height are set.
- Check CSS is not setting height to 0 or display to none.
- Try giving the map container a fixed height like 400px and see if it shows.
b) JavaScript API embed
- Example script:
- Things to check:
- The callback function name matches exactly.
- The initMap function is defined before the script finishes loading.
- No JS errors earlier on the page that stop scripts.
- After layout changes, if you moved scripts around or wrapped them in modules, the global initMap might not be accessible anymore.
-
CSS / layout problems
- Use DevTools, pick the map element.
- Look at computed height and width.
- If height is 0, you will see gray or nothing.
- Set CSS like:
#map { width: 100%; height: 400px; } - Check parent elements for overflow hidden or flex settings that collapse the map.
-
Mixed content and protocol
- If your page is https and the map script is http, browser blocks it.
- Make sure script src starts with https.
- Same for iframe src.
-
Script order issues after your update
- If you started bundling scripts, your initMap might sit in a local scope.
- For Google Maps callback to work, initMap must be on window.
Example:
window.initMap = function() {
// map init code
}; - Also check you do not load the Maps API script twice.
If you post the exact error message from the browser console, the line where you load the map, and whether it is iframe or JS API, people can narrow it down fast. Without that, common causes are: referrer restriction mismatch, missing API enablement, billing disabled, or map container height set to 0 after the layout change.
Given you changed layout and scripts right before it broke, I’d actually start by trying to prove it’s not an API/billing issue before tearing apart the key config. @reveurdenuit already covered the standard Google Cloud checks pretty thoroughly, so here’s how I’d try to isolate the problem from a different angle:
-
Create a dumb test page
Make a completely stripped‑down HTML file on the same domain as your live page, something like:<html> <head> <style> #map { width: 100%; height: 400px; } </style> </head> <body> <div id='map'></div> <script> window.initMap = function () { new google.maps.Map(document.getElementById('map'), { center: { lat: 37.7749, lng: -122.4194 }, zoom: 12 }); }; </script> <script src='https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&callback=initMap' async defer></script> </body> </html>Upload that next to your site and open it directly in the browser.
- If this works fine, then your key, APIs, billing and referrer restrictions are almost certainly OK. The issue is your new layout/scripts.
- If this also fails, then yeah, you’re probably looking at a key, billing, referrer, or API enablement problem.
-
Temporarily nuke restrictions (for testing)
This is where I slightly disagree with the very conservative approach a lot of people take. For debugging, I’ll often:- In Google Cloud Console, remove HTTP referrer restrictions from the key for a few minutes.
- Hard refresh your test page (Ctrl+F5).
If the test page suddenly starts working after removing restrictions, you know the layout changes coincided with a host/URL or protocol change that no longer matches the referrer rules. Then you can re‑add restrictions correctly (e.g.
https://example.com/*andhttps://www.example.com/*). -
Check what the map “looks” like in DevTools, not just if it errors
Sometimes Maps technically loads fine but renders as a gray box or offscreen because of layout changes. Click the map container in DevTools and look at:- Actual pixel size in the layout panel. If you see
0 x 0or something tiny, that’s your bug. - Any transforms:
transform: translateX(...),scale(0)or weird flex behavior. - Positioning: absolutely positioned inside a parent with
overflow: hiddencan clip it out of view.
Even if @reveurdenuit mentioned height issues, the tricky part with newer layouts is grid/flex: a parent set to
display: flexwithflex: 0on the map container will visually kill it without any console errors. - Actual pixel size in the layout panel. If you see
-
Look for race conditions you introduced
When people “clean up” scripts, a really common failure is:- Moving map init code to a module (
type='module') - Or bundling everything with Webpack/Vite/Rollup and suddenly
initMapis no longer onwindow
Quick checks:
-
Search your code for
initMap. Is it now inside an IIFE or module? If yes, expose it:window.initMap = function () { // your actual init code }; -
Make sure you don’t have any new
defered scripts that throw errors before Maps runs. One benign looking error early in your bundle can prevent your init logic from executing even if the Maps script loaded fine.
- Moving map init code to a module (
-
If you’re using an iframe embed, assume CSS is guilty first
For an<iframe>style embed, instead of only checking width/height, toggle CSS live:- In DevTools, on the map’s parent containers, uncheck things like:
position: absolutedisplay: flexordisplay: gridoverflow: hidden- Any
height: 100%when the parent has no explicit height
I’ve seen more “broken maps” that were actually “perfectly working maps inside a 0px‑tall flex child” than genuine API failures.
- In DevTools, on the map’s parent containers, uncheck things like:
-
Compare old vs new quickly
If you have git or any version control:diffjust the HTML template and main JS file related to the page where the map lives.- Look specifically for:
- Changes to the script tag that loads Maps (query params, key, callback, protocol)
- New wrappers around the map element (extra divs, new grid/flex containers)
- New JS that touches
#map,google.maps, or modifies the same container
Even a quick manual “copy old code into a temp file and paste it back in place” test can tell you if something in the new layout is the problem. If reverting the template but keeping the same API key makes it work again, that’s huge info.
If you can paste:
- The snippet you’re using to embed the map (iframe or JS)
- A screenshot or copy of any message in the browser console (even if it doesn’t look like a Maps error)
…it’s usually possible to say “this is 100% a layout/scope problem” vs “nope, your key or referrers are busted” pretty fast.
Given what @viajantedoceu and @reveurdenuit already covered from the Google Cloud side, I’d attack this from the “what exactly changed in your layout/scripts” angle, because that’s often where Maps quietly dies without obvious API errors.
Analytical breakdown of things they did not emphasize as much:
-
Check if your map container is ever visible when Maps initializes
If your new layout uses tabs, accordions, carousels, or “hidden until click” sections, and the map lives inside the hidden part, Maps will usually render a blank/gray area.Test:
- Put the map in a simple visible div at the top of the page (temporarily).
- If it works there but not in the final UI, you need to trigger a resize after it becomes visible:
google.maps.event.trigger(map, 'resize'); map.setCenter(originalCenter);Call that right after you show the tab/modal.
-
Verify you are not reusing the same container or map instance incorrectly
After refactoring JS, people sometimes runinitMapmultiple times or try to mount multiple maps into the same DOM node.Symptoms:
- Map shows for a second, then disappears when another init runs.
- Only one of several maps shows.
Fix:
- Log whenever
initMapis called. - Make sure each map has its own container div with a unique ID.
- Guard against multiple inits:
if (!window._mapInitialized) { window._mapInitialized = true; // init map here } -
Module / bundler side effects that are not just about
initMap
@reveurdenuit rightly focused onwindow.initMap, but newer builds often break Maps by tree-shaking or by lazy loading incorrectly.Things to watch:
-
If you now import your map logic in a dynamic import (
import('./map.js')) that runs only after some event, and the script tag still usescallback=initMap, Google will callinitMapbefore that module is even imported. -
Either remove the
callbackparameter and call your init manually after script load:const script = document.createElement('script'); script.src = 'https://maps.googleapis.com/maps/api/js?key=KEY'; script.onload = () => { initMap(); }; document.head.appendChild(script);or make sure your module defines
window.initMapsynchronously.
-
-
Z-index and overlay issues from the new layout
Maps might actually be there but covered by some other layout layer like a sticky header, an overlay, or a full-width element with higher z-index.In DevTools:
- Inspect the actual map tiles (the images inside the map div).
- Look for any absolutely positioned elements on top with
z-indexgreater than the map container. - Temporarily disable those styles. If the map suddenly appears, adjust z-index or clipping.
-
Event listener conflicts
New scripts can intercept pointer or scroll events, making the map feel dead or partially non-responsive even if it is visible.Common offenders:
- Global
touchstart/touchmovehandlers that callpreventDefault()without conditions. - Custom drag/scroll libraries attached to the same container.
Quick test:
- Disable your new main bundle or layout script and reload the page with only the old map code.
- If the map works, re-enable pieces of the bundle until you find the script that hijacks events around the map div.
- Global
-
Performance / timing regressions
If you introduced heavy scripts or big layout reflows, the Maps API might be loading fine but the page locks up so long that it appears broken.- Use Performance panel in DevTools.
- If you see a giant long task right as the Maps script should run, move that code later or break it up.
- You can also wrap your
initMapinrequestIdleCallbackorsetTimeoutto let the initial layout settle, although I do not usually like that unless you know performance is the root cause.
-
Sanity check: content security policy (CSP)
If you added or tightened CSP headers during your update, Maps can be silently blocked without the usual “API key” errors.Look for a response header like
Content-Security-Policy.
Ensure thatscript-src,frame-src, andimg-srcallow the necessary Google domains. If not, add the correct sources and reload. This is one place where I mildly disagree with the general “just check console for Google errors” approach: CSP failures can look more like generic blocked-resource noise unless you know to look for them.
About using a “product” or helper pattern like a pre-built map wrapper (you left the product title blank, so I will talk generically):
Pros:
- Can abstract away the callback,
window.initMap, and script-loading headaches. - Often gives a cleaner, component-style interface that plays better with modern frameworks.
- Easier to swap between simple embeds and fully interactive maps.
Cons:
- Adds another dependency and layer of abstraction to debug.
- Might lag behind Google API changes.
- Can hide key details like when exactly the script loads or how the map is attached to the DOM, which is where your current bug probably lives.
Compared with what @viajantedoceu and @reveurdenuit already suggested (API key, billing, restrictions, container height, and a minimal test page), the angle here is:
- Assume the Google side is fine once your minimal test page passes,
- Then surgically check visibility, timing, event listeners, z-index, modules, and CSP in the updated layout.
If you can share:
- The HTML around the map container,
- The script tag that loads Maps,
- And where
initMapis defined in your new build,
you can usually pinpoint the culprit in a couple of diffs rather than redoing your whole API setup.