Leaflet.js Tile Layers — Map Providers and Custom Tiles
In this tutorial, you will learn about Leaflet.js Tile Layers. We cover key concepts, practical examples, and best practices to help you master this topic.
Leaflet.js tile layers display map imagery from various providers like OpenStreetMap and Mapbox, with configurable attribution, subdomains, and loading behavior.
What You'll Learn
By the end of this guide, you will configure multiple tile providers, create a custom tile layer from your own server, implement base map layer switching, handle tile load errors, and optimize tile loading performance.
OpenStreetMap Tiles
var map = L.map('map').setView([40.7128, -74.0060], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
maxZoom: 19
}).addTo(map);
Layer Switching
var osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OSM'
});
var satellite = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: '© Esri'
});
var baseMaps = {
'Street': osm,
'Satellite': satellite
};
L.control.layers(baseMaps).addTo(map);
osm.addTo(map);
Custom Tile Layer
var customTiles = L.tileLayer('https://tiles.example.com/{z}/{x}/{y}.png', {
attribution: '© My Tiles',
subdomains: ['a', 'b', 'c'],
minZoom: 5,
maxZoom: 18,
tileSize: 256
});
Common Mistakes
1. Missing Attribution
All tile providers require attribution. Omitting it violates terms of service.
2. Wrong Tile URL Format
Tile URLs follow {z}/{x}/{y}.png format. Using {x}/{y}/{z} or different file extensions breaks loading.
3. Not Setting maxZoom
Without maxZoom, the zoom control zooms to levels with no tiles, showing blank areas.
4. Too Many Tile Layers Active
Each tile layer loads many HTTP requests. Only show one base layer at a time.
5. Subdomain Not Optimized
Browsers limit concurrent connections per domain. Use subdomains ['a', 'b', 'c'] for parallel loading.
Practice Questions
Q1: What is the default tile provider for Leaflet? A: Leaflet does not include a default provider. You must add a tile layer explicitly.
Q2: How do tile URLs work? A: Tiles are 256x256 images at z/x/y coordinates. {z}=zoom, {x}=column, {y}=row.
Q3: How do you add multiple base maps? A: Use L.control.layers with an object of named tile layers for base map switching.
Q4: What is the maxZoom default? A: Leaflet default maxZoom is 18. OpenStreetMap tiles go to 19.
Q5: How do you handle tile loading errors? A: Listen for the 'tileerror' event on the tile layer and replace with a placeholder image.
Challenge: Build a map with 4 base layers (street, satellite, terrain, dark) using different providers. Add a scale control.
FAQ
Try It Yourself
Build a map with base layer switching.
<!DOCTYPE html>
<html>
<head>
<title>Tile Layers Demo</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9/dist/leaflet.js"></script>
</head>
<body style="font-family:sans-serif;padding:20px;">
<h2>Tile Layer Switching</h2>
<div id="map" style="height:400px;border-radius:8px;"></div>
<script>
var map = L.map('map').setView([40.7128, -74.0060], 12);
var street = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap'
});
var dark = L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
attribution: '© CARTO'
});
var terrain = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
attribution: '© OpenTopoMap'
});
L.control.layers({
'Street': street,
'Dark': dark,
'Terrain': terrain
}).addTo(map);
street.addTo(map);
</script>
</body>
</html>
What's Next
Work with GeoJSON data.
GeoJSON — Working with GeoJSON. Clustering — Marker clustering.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro