Raster tiles are pictures of the map. They're simple and they work everywhere, but what you get is what you get. Vector tiles send the map data itself (roads, buildings, labels) and let the browser draw it. That means the map stays sharp on any screen, zooming is smooth, you can rotate and tilt it, and you can restyle it instantly.
In this post we'll use TMaps vector tiles with MapLibre GL JS, the open-source WebGL map library, and build a little style switcher with four styles.
Live demo: examples.tmaps.tn/03-vector-maplibre-styles
How TMaps vector tiles work
You don't request the tiles yourself. Each style is a JSON document that follows the Mapbox Style Specification:
https://tiles.tmaps.tn/v-tile/{style}.json?api_key=YOUR_API_KEY
That JSON lists the tile sources, the fonts (glyphs), the icons (sprites) and how every layer should be drawn. MapLibre reads it and fetches the rest on its own. There are four styles to choose from:
| Style | Good for |
|---|---|
streets |
Everyday reference map, easy to read streets and points of interest |
dark |
Dashboards and night mode |
terrain |
Relief, rivers and topography |
sunny |
Tourism and retail, warmer colours |
1. A first vector map
You'll need a TMaps API key from the TMaps console, with your domain (and localhost) in its Authorized Domains.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Vector map of Tunisia</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/maplibre-gl.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/maplibre-gl.js"></script>
<style>
html, body, #map { height: 100%; margin: 0; }
</style>
</head>
<body>
<div id="map"></div>
<script>
const API_KEY = 'YOUR_API_KEY';
const map = new maplibregl.Map({
container: 'map',
style: `https://tiles.tmaps.tn/v-tile/streets.json?api_key=${API_KEY}`,
center: [10.1815, 36.8002], // Tunis, as [lng, lat]
zoom: 12,
maxZoom: 18,
});
map.addControl(new maplibregl.NavigationControl(), 'top-right');
</script>
</body>
</html>
One thing to watch: MapLibre takes [longitude, latitude], the opposite of Leaflet's [lat, lng]. Mixing them up is the most common reason a map opens in the middle of the ocean.
2. Switch styles without reloading the map
map.setStyle(url) swaps the style but keeps the map, its position and its controls. A basic switcher is only a few lines:
const styleUrl = (name) => `https://tiles.tmaps.tn/v-tile/${name}.json?api_key=${API_KEY}`;
for (const name of ['streets', 'dark', 'terrain', 'sunny']) {
const button = document.createElement('button');
button.textContent = name;
button.addEventListener('click', () => map.setStyle(styleUrl(name)));
document.body.append(button);
}
Here's the same view of Tunis in the other three styles. First dark, which works well on dashboards:
Then terrain:
And sunny:
Follow the user's dark mode
Since switching is instant, you can simply follow the operating system's theme:
const dark = window.matchMedia('(prefers-color-scheme: dark)');
const applyTheme = () => map.setStyle(styleUrl(dark.matches ? 'dark' : 'streets'));
dark.addEventListener('change', applyTheme);
applyTheme();
3. Tilt and rotate
The map is drawn with WebGL, so you can tilt and rotate it, which raster tiles simply can't do:
map.jumpTo({
center: [10.179, 36.799], // Medina of Tunis
zoom: 15.5,
pitch: 60, // tilt, in degrees
bearing: -25, // rotation, in degrees
});
Users can do the same thing themselves with a right-click drag on desktop, or two fingers on a phone.
4. Customize a style
The style JSON is yours to tweak. Download it, change the layers (colours, fonts, which labels show up at which zoom), and host your own copy. Just keep two things in mind:
- the tile URLs in
sourcesmust still point totiles.tmaps.tnwith yourapi_key, because that's how your usage is authenticated; - you're free to change
layers, and alsoglyphsandspriteif you host your own fonts and icons.
Raster or vector?
| Raster | Vector | |
|---|---|---|
| Libraries | Leaflet, OpenLayers, any XYZ client | MapLibre GL JS, MapLibre Native |
| High-density screens | Blurry (no @2x yet) | Always sharp |
| Changing the style | Needs new tiles | Instant, in the browser |
| Rotate and tilt | No | Yes |
| Older devices | Very light | Needs WebGL |
For a simple map embedded in a page, raster tiles with Leaflet are hard to beat (that's the first post of this series). When the map is the heart of your product, go vector.
Going further
- About TMaps: Tunisia maps, geocoding and routing API
- Live demos: examples.tmaps.tn
- Source code, MIT licensed: github.com/tmaps-tn/tmaps-snippets
- Postman collection: postman.com/tmaps-tn/tmaps-api
- Vector tiles documentation: tmaps.tn/documentation
Questions or feedback? Leave a comment or write to [email protected].






Top comments (0)