Skip to content
Add a Hillshade Layer

Add a Hillshade Layer in Maptoolkit Maps JS

A hillshade layer simulates sunlight hitting a terrain surface to produce shadows that make mountains and valleys visually clear. In Maptoolkit Maps JS, you add a raster-dem source and a hillshade layer on top of it to enable this effect. Use hillshade to give topographic context to hiking maps, ski resort apps, or any visualization where understanding terrain shape matters.

const API_KEY = 'YOUR_API_KEY';

    const map = new maptoolkit.Map({
        container: 'map',
        apiKey: API_KEY,
        style: {
            version: 8,
            sources: {
                'dem': {
                    type: 'raster-dem',
                    tiles: [`https://tiles.maptoolkit.net/terrain/{z}/{x}/{y}.webp?api_key=${API_KEY}`],
                    tileSize: 256,
                    minzoom: 5,
                    maxzoom: 12,
                    encoding: 'terrarium'
                }
            },
            layers: [{
                id: 'hillshading',
                type: 'hillshade',
                source: 'dem',
                paint: {
                    'hillshade-exaggeration': 0.5,
                    'hillshade-shadow-color': '#473b24'
                }
            }]
        },
        center: [11.39085, 47.27574],
        zoom: 10,
        attributionControl: { compact: false }
    });
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Add a Hillshade Layer - Maptoolkit Maps JS</title>
    <meta property="og:description" content="Add a hillshade layer to visualize terrain relief." />
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://unpkg.com/@maptoolkit/maps@11.0.0-beta.3/dist/maptoolkit.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/@maptoolkit/maps@11.0.0-beta.3/dist/maptoolkit.css" />
    <style>
        html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
        #map { width: 100%; height: 100%; }
    </style>
</head>
<body>
<div id="map"></div>
<script>
    const API_KEY = 'YOUR_API_KEY';

    const map = new maptoolkit.Map({
        container: 'map',
        apiKey: API_KEY,
        style: {
            version: 8,
            sources: {
                'dem': {
                    type: 'raster-dem',
                    tiles: [`https://tiles.maptoolkit.net/terrain/{z}/{x}/{y}.webp?api_key=${API_KEY}`],
                    tileSize: 256,
                    minzoom: 5,
                    maxzoom: 12,
                    encoding: 'terrarium'
                }
            },
            layers: [{
                id: 'hillshading',
                type: 'hillshade',
                source: 'dem',
                paint: {
                    'hillshade-exaggeration': 0.5,
                    'hillshade-shadow-color': '#473b24'
                }
            }]
        },
        center: [11.39085, 47.27574],
        zoom: 10,
        attributionControl: { compact: false }
    });
</script>
</body>
</html>

Use the prompt below with any LLM to get the same result. Make sure the Maptoolkit MCP server is connected first — check out AI Integration & MCP to get started.

Use the Maptoolkit Connector. Create an interactive map with zoom level 10, centered around [11.39085, 47.27574], displaying a hillshade layer.

How it works

The hillshade effect needs two pieces: a source that carries elevation, and a layer that shades it.

The source is raster-dem, not raster. A raster source would draw the tiles as a picture; raster-dem tells the renderer to read each pixel as a height value and compute slope from it.

encoding: 'terrarium' is required and is easy to get wrong. The Maptoolkit terrain tiles are Terrarium-encoded even though the endpoint path says terrain and some tooling assumes Mapbox Terrain-RGB. Passing the wrong encoding does not raise an error: the renderer decodes the same pixels with the wrong formula and produces plausible but incorrect terrain.

minzoom: 5 and maxzoom: 12 describe the tileset, not a display preference. Zoom 12 is the maximum the terrain tileset holds, so the renderer overzooms beyond it rather than fetching more detail. Requesting a tile outside this range returns 404, not an empty tile.

hillshade-exaggeration runs from 0 to 1 and controls how strongly slope becomes shadow. The 0.5 here is a middle setting that reads well over a base map. Push it toward 1 for dramatic relief in alpine terrain, and lower it when labels and roads start competing with the shading.

Next steps

The first thing to reach for is the rest of the paint properties. Exaggeration, the shadow and highlight colours and the illumination direction change the character of the relief completely, and a warm shadow over a summer basemap reads very differently from a cold one over a winter map.

Hillshading is background, so the next build is usually what goes on top of it: a route, a set of huts or trailheads, a boundary. For measured heights rather than shading, the Elevation API gives numbers you can label or chart.