This project is not covered by Drupal’s security advisory policy.

Puts you in your place.
Every map at its best zoom, plus the surrounding area. Drawn on your server from map tiles your site keeps. No API key, no per-load billing, no third party watching who looks at what.
Documentation Source code Issue queue See it live
1.0.0-alpha1. Requires Drupal 11.2 or later and PHP 8.3 (64-bit) with zlib, plus a private file system path. Alphas carry no upgrade path: uninstall and reinstall between them. Stored tiles are kept across reinstalls, so nothing is downloaded twice. From beta1, every change comes with an update.
Maps on nodes and in views
Each map is a fixed block of tiles, from 2 × 2 to 4 × 4, framed on its places at the closest zoom that holds them all.
On a node's page, place the Maper map block. It maps that node, or the nodes it references through a field (an event's venue, a tour's dates), each placed by the site's latitude and longitude fields or a Maper point field. Its settings pick the map type and which fields fill each pointer's card.
In a view, choose the Maper map format. Every result row becomes a pointer, placed by the row's coordinate fields, and the map frames all of them. The card's parts are filled from the row's fields.
Styles and layers
Restyling in place, no fetch needed
Map tiles carry shapes and names, not colours. A map style is the full set of colours a map is drawn in: ground, parks, water, roads, buildings, labels, the pointers and the card. Switch a map to another style, or edit one, and every map using it is drawn again from the tiles the site already holds. Light, Pearl and Dark ship in 1.0.0-alpha1; Ink, Antique, Blueprint, Terracotta and Neon join them in the next release. A new style starts as a copy of any of them and is edited colour by colour.
Six layers, switched on one at a time
A map is drawn in layers, bottom to top: the ground; areas and water; lines, meaning roads, rail and rivers; buildings; names; points of interest. A map style decides which layers are drawn and from which zoom each one starts. The shipped styles start buildings and points of interest at zoom 16, close enough to read a street.
Every tile is downloaded once and kept
Tiles are stored on the server, in the site's private files. Browsers never receive tiles, only the finished drawing, and a tile downloaded for one map serves every other map that covers the same ground.
Downloading stays switched off until the site sets a contact address. That address goes with every request, so the tile provider knows who is asking and how to reach the site. From then on, every download is held to these limits:
| Limit | Default |
|---|---|
| Tiles per job (a larger job is refused, not cut short) | 5,000 |
| Size per job, estimated from tiles already held | 200 MB |
| Tiles per day | 20,000 |
| Pause between requests, one at a time | 250 ms |
| Downloads triggered per reader, per hour | 60 |
| Tiles for one step of the zoom slider | 16 at most |
Requests go over HTTPS to one host only, and wait when the provider answers 429 or 503. On Oído en Vivo: 836 tiles, 69 MB, serving the maps of 550 places and every search.
What the admin pages show
Draw one place with each tile provider and compare them. Edit a style while its preview updates. Pick a grid size like a table. See which map items each provider's tiles actually contain, and how much of the site's maps the stored tiles already cover. These pages read what is stored; none of them downloads anything.
Using maper from your own front end
Maper can hand a map to any front end as data instead of rendering it into a Drupal page.
- Issue the map on the server. In PHP, call the map builder with the points. It stores the map, draws nothing, and returns an address. The points never leave the server.
$issued = \Drupal::service('maper.map_builder') ->issue($points, ['type' => 'overview']); // $issued['endpoint'] = '/maper/frame/{token}' - Fetch the map as JSON.
GET /maper/frame/{token}returns the map; add?zoom=Nfor another step of the slider. The reader's role needs the View maper maps permission, and the address answers only readers with the same permissions it was issued for. A logged-in reader sends the session's CSRF token, from/session/token, in anX-CSRF-Tokenheader. - Draw it with maper's skin, or your own. With maper's skin: attach the
maper/headlesslibrary, put<div data-maper-headless="/maper/frame/{token}"></div>in the page (plusdata-maper-session-token="/session/token"for logged-in readers), and the script callsMaperFrame.mountPayload(node, payload). With your own: read the JSON directly.svgis the drawn map,markershold each pointer's pixel position, label, link and card,rangelists the zoom steps and which are already stored, andattributionis the tile credit, which must be shown. - Copy the reference script.
js/maper-headless.jsis a complete front end in plain JavaScript with no Drupal dependency. The Headless tab in the admin runs it on a live map and shows the JSON it received. The README's "A headless consumer" and "The payload (schema 1)" sections list every field.
Install
composer require drupal/maper:1.0.0-alpha1
composer require npm-asset/vue:3.5.43 # via asset-packagist
drush en maper_openfreemapUse maper_protomaps instead to read a PMTiles file you place yourself; nothing is downloaded then.
Serve Vue from your site. The map skin needs Vue 3.5.43 at /libraries/vue; add asset-packagist as a Composer repository and require npm-asset/vue as above. Without it, the skin loads the same Vue release from jsDelivr, checked against its hash, and the status report says so.
Also included
- A point field type and the Maper locator formatter.
- Place cards with a fixed layout, each part filled from a field, respecting field access for every reader.
- Label rules per layer: drop a word every district name repeats, prefer names in the site's language.
- Maper: Nominatim, experimental: finds coordinates for nodes that have none. Off until the site chooses a Nominatim server and accepts its usage policy.
Credits
Map data © OpenStreetMap contributors, available under the Open Database License. Tiles from OpenFreeMap (OpenMapTiles schema) or Protomaps. Built and run in production on Oído en Vivo.
Project information
- Project categories: Content display, Decoupled
5 sites report using this module
- Created by oneliner on , updated
This project is not covered by the security advisory policy.
Use at your own risk! It may have publicly disclosed vulnerabilities.










