How to Add a Map to a Website: Google Maps, Yandex Maps, Leaflet
Practice4 minInnovialabs editorial team
In short
For a single "how to find us" pin, an iframe embed is enough; for many markers and custom logic use a JS API or Leaflet, and load the map lazily only when the visitor scrolls to it.
The short answer
For a contact page with one address, an embedded iframe from Google Maps or Yandex Maps is enough: no code, a couple of minutes of work. If the map needs many points (branches, pickup locations), filters or custom marker styling, you need an interactive JS map: the Google Maps JavaScript API, the Yandex Maps API or the open-source Leaflet library.
Either way, a map is heavy: scripts, tiles, fonts. So the main rule is do not load it upfront — load it only when it is actually needed.
Comparing providers
| Google Maps | Yandex Maps | Leaflet + tiles | |
|---|---|---|---|
| Coverage in Uzbekistan | good for major cities, address detail weaker in places | usually more detailed for streets and buildings in CIS cities | depends on the tile source (OpenStreetMap and others) |
| Simple iframe | yes, via "Share" | yes, via the Map Constructor | no, JS only |
| API key | required for the JS API and Embed API, needs a billing account | required for the JS API | none for the library itself, may be needed by the tile provider |
| Pricing model | free quota, then per request | free terms with restrictions, commercial plans | library is free, you pay the tile provider at high volume |
Pricing and limits change over time for every provider, so check the current terms before launch. Also check coverage on your own addresses: open the relevant neighbourhood in each service and see whether it shows the building numbers and street names your customers actually use.
Option 1: an iframe in five minutes
- Find the address on the map.
- In Google Maps: "Share" → "Embed a map". In Yandex Maps: the Map Constructor, where you can place a pin and a label.
- Copy the code and paste it into the page.
<iframe
src="https://www.google.com/maps/embed?pb=..."
width="100%" height="400"
style="border:0"
loading="lazy"
title="Map to our office"
referrerpolicy="no-referrer-when-downgrade">
</iframe>
The loading="lazy" attribute already helps a lot: the browser skips the iframe until it gets close to the viewport. Do not forget title — screen readers announce it.
Option 2: an interactive map with markers in Leaflet
Leaflet is a lightweight open-source library. It can take tiles (the map images) from any provider.
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<div id="map" style="height:400px"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
const map = L.map("map").setView([41.311, 69.279], 12);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19,
attribution: "© OpenStreetMap contributors"
}).addTo(map);
const offices = [
{ name: "Office 1", coords: [41.311, 69.279] },
{ name: "Office 2", coords: [41.338, 69.334] }
];
offices.forEach(o => L.marker(o.coords).addTo(map).bindPopup(o.name));
</script>
Note that the public OpenStreetMap tile servers have a usage policy and are not meant for high-traffic commercial projects. In production, use a commercial tile provider or host your own tile server. Never remove the data attribution.
With Google and Yandex the logic is the same: load the script with your key, create a map in a container, add markers from an array. Restrict the key by domain (HTTP referrer) in the provider console, otherwise others can use it on their sites at your expense.
Keeping the page fast
- Lazy loading. Load the map script only when the container comes near the viewport.
- Facade. Show a static map image with an "Open map" button and load the real map on click.
- Fixed container height, so the layout does not jump while the map loads (CLS).
- Keep the map out of the first screen unless it is the page's main purpose.
- Marker clustering when you have hundreds of points, otherwise the map lags on phones.
const el = document.getElementById("map");
const io = new IntersectionObserver(async ([entry]) => {
if (!entry.isIntersecting) return;
io.disconnect();
const { initMap } = await import("./map.js");
initMap(el);
}, { rootMargin: "200px" });
io.observe(el);
Common mistakes
- An API key with no domain restrictions.
- A full-width map on mobile that traps the finger, so the page cannot be scrolled. Disable one-finger dragging or make the map shorter.
- No text address next to the map. Both people and search engines need the address as text.
- Several map providers on one site — extra weight with no benefit.