How to Add an Interactive Map to Your Website with JavaScript (Leaflet Example)

You can embed a fully interactive map into your website in about ten minutes using JavaScript and the Leaflet library. This beginner-friendly guide provides a complete, working code example you can copy and paste to get a map with markers and popups running on your own page. We’ll walk through each step, from setting up the HTML to adding tiles and interactive elements, explaining the core concepts as we go.

Why Leaflet is the Perfect Starting Point for Web Maps

When you need to add a simple, interactive map to a website, Leaflet is often the best tool for the job. It is a lightweight, open-source JavaScript library designed specifically for mobile-friendly interactive maps. Think of it as the Swiss Army knife for straightforward web mapping tasks.

Leaflet excels at the fundamentals: displaying tile layers, adding markers, handling popups, and responding to user clicks and drags. Its API is clean and well-documented, making it incredibly approachable for developers new to mapping. While heavier libraries like Mapbox GL JS or OpenLayers offer advanced features for vector tiles or complex GIS operations, their learning curve is steeper. For the common goal of “put a map with a few points on my site,” Leaflet’s simplicity and focused toolkit make it an ideal choice. It also has a massive plugin ecosystem for when you need to add features like clustering, heatmaps, or custom controls.

What You’ll Build: A Glimpse at the Final Interactive Map

By the end of this tutorial, you will have a fully functional map embedded in an HTML page. The map will be centered on a location of your choice (we’ll use London as an example), complete with standard zoom and drag controls. You’ll add a marker at a specific point, and clicking that marker will open a popup with custom text. This is the foundational pattern for countless use cases, from showing store locations to visualizing event data.

Step 1: Setting Up Your HTML File and Including Leaflet

Every web map starts with a basic HTML page. You need to include Leaflet’s CSS and JavaScript files, which provide the styling and logic for the map, and create a container element where the map will live.

Here is the complete boilerplate HTML structure. The key parts are the links to Leaflet’s CSS and JS from a CDN (Content Delivery Network) and the <div> with the id “map”.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Interactive Map</title>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
     integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
     crossorigin="" />
    <style>
        #map { height: 500px; }
    </style>
</head>
<body>
    <h1>My First Map</h1>
    <div id="map"></div>

    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
     integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
     crossorigin=""></script>
    <script src="script.js"></script>
</body>
</html>

Understanding the Key Ingredients: HTML, CSS, and JS

Each part of this setup has a specific role. The HTML provides the page structure and the <div id="map"> container. The linked Leaflet CSS file styles all map elements—the tiles, controls, and markers—so they look correct. The linked Leaflet JavaScript file is the library itself, giving you access to all the functions like L.map() and L.marker(). The inline CSS rule #map { height: 500px; } is crucial; without a defined height, the map container will have zero height and your map will be invisible.

Step 2: Initializing Your Map with JavaScript

With the HTML skeleton ready, you now use JavaScript to bring the map to life. This happens in a separate script.js file or in a <script> tag before the closing </body>.

The core function is L.map(). It takes the ID of your HTML container and creates a map object within it. You then use the .setView() method to define where the map is centered and at what zoom level it starts.

// Initialize the map and set its view to London
const map = L.map('map').setView([51.505, -0.09], 13);

Choosing Coordinates and Zoom Level

The two numbers in the array [51.505, -0.09] are latitude and longitude. You can find these coordinates for any place using tools like Google Maps. The second parameter, 13, is the zoom level. A zoom level of 1 shows the entire world, while levels around 13-15 show a city in detail, and 18+ shows individual buildings. Experiment with this number to get the right initial view for your data.

Step 3: Adding Map Tiles (The Visual Layer)

If you run the code now, you’ll get a draggable gray square. That’s because you’ve created the map interface but haven’t added any visual map data. The streets, labels, and terrain come from a tile layer—a service that serves small image squares that Leaflet stitches together seamlessly.

You can add a tile layer using L.tileLayer(). We’ll use OpenStreetMap’s free tiles as an example. You must provide a URL template and an attribution string.

// Add OpenStreetMap tile layer
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
}).addTo(map);

The .addTo(map) method adds this tile layer to your map instance. The {s}, {z}, {x}, and {y} in the URL are placeholders Leaflet replaces with the correct server, zoom level, and tile coordinates.

Step 4: Placing a Marker and Popup on the Map

Markers are the classic way to highlight points on a map. In Leaflet, creating one is straightforward. You define its location with coordinates and add it to the map. You can then attach a popup with information.

// Add a marker at a specific location
const marker = L.marker([51.5, -0.09]).addTo(map);

// Bind a popup to the marker
marker.bindPopup("Hello world!
This is a popup.").openPopup();

The L.marker() function creates the marker object. .bindPopup() attaches an HTML string to it that will display when clicked. Calling .openPopup() immediately opens the popup when the map loads; omit this line if you want the popup to appear only on click.

Your Complete, Working Code Example

Here is the entire code in one file. Copy this into an index.html file and open it in a web browser to see your interactive map.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Leaflet Map Tutorial</title>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
     integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
     crossorigin="" />
    <style>
        #map { height: 500px; }
    </style>
</head>
<body>
    <h1>My Interactive Map</h1>
    <div id="map"></div>

    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
     integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
     crossorigin=""></script>
    <script>
        // Initialize map
        const map = L.map('map').setView([51.505, -0.09], 13);

        // Add tile layer
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap contributors'
        }).addTo(map);

        // Add a marker with a popup
        const marker = L.marker([51.5, -0.09]).addTo(map);
        marker.bindPopup("Hello world!
This is a popup.").openPopup(); </script> </body> </html>

Next Steps: Where to Go From Here

You now have a foundational interactive map. The real power comes from building on this pattern. You could add multiple markers by calling L.marker() repeatedly, perhaps using data from an array. For better performance with dozens or hundreds of markers, you would explore marker clustering plugins. To display complex geographic shapes like polygons or lines, you would learn to use GeoJSON with Leaflet’s L.geoJSON() layer. Other next steps include customizing marker icons, adding a control to search for places (geocoding), or switching to different tile providers for alternative map styles.

Troubleshooting Common Issues

If your map doesn’t appear, check these common problems first:

  • The map container has no height. This is the most frequent issue. Ensure your #map CSS selector sets a height (e.g., 500px or 80vh).
  • Leaflet CSS is missing. Without the CSS, map tiles and controls may be misaligned or invisible. Verify the <link> to the Leaflet CSS is present and loads without errors.
  • Script order is wrong. Your custom script that calls L.map() must be placed after the script that loads the Leaflet library.
  • Browser console errors. Open your browser’s developer tools (F12). Look in the Console tab for errors related to failed resource loads (like the CDN links being blocked) or JavaScript syntax errors.
  • Tile layer not loading. Some networks or ad-blockers may block tile servers. Try a different tile provider URL or check your network connection.
Scroll to Top