# what
A tutorial/guide for myself[1] to embed leaflet maps on this site.
# how
# imports
Leafet.js
requires importing (a) some css
and (b) some javascript
.
I have a file: _includes/partials/leafletHeader.njk
, the contents of which looks a lot like:
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<!-- full screen code -->
<script src="https://cdn.jsdelivr.net/npm/leaflet.fullscreen@3.0.0/Control.FullScreen.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet.fullscreen@3.0.0/Control.FullScreen.css"/>
That is straight from the docs. The first line is the css
; the second the js
. The third and fourth lines are for importing the full-screen plugin[2].
In my layouts/base.njk
template there is the following nunjucks
snippet within the <head>
:
{% if leaflet %}
{% include "partials/leafletHeader.njk" %}
{% endif %}
This pipes the contents of leafletHeader.njk
into the html <head>
if I include leaflet: true
in my post's frontmatter.
# code for the map
Again, straight from the docs, we need the following js
:
var map = L.map('map').setView([0, 0], 1);
const tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
L.control.fullscreen({
"position": "topleft",
"title": "Full Screen",
"titleCancel": "Exit Full Screen",
"forceSeparateButton": false,
}).addTo(map);
This creates a map centered on Null Island (0.0°N, 0.0°E), with a zoom level of 1; with OSM's default tile & attribution; also added is a full screen toggle. Great.
This code sits in src/js/leafletMap.js
. This gets passed through during build. Meaning it gets copied wholesale, rather than injected. See for yourself.
Putting the map on the page requires a container and linking to the js
.
<div id="map" style="height:400px"></div>
<script src="/js/leafletMap.js"></script>
# adding complexity
Layers and click events and and pop-ups etc... can all be added by linking to additional javascript
files. These should all be in js
, or a subdirectory within[3] . A another <script>
tag is all that is required.
<script src="js/leafletExample/example.js"></script>
where js/leafletExample/example.js
looks a bit like:
var geojsonFeature = {
"type": "Feature",
"properties": {
"name": "Coors Field",
"amenity": "Baseball Stadium",
"popupContent": "This is where the Rockies play!"
},
"geometry": {
"type": "Point",
"coordinates": [-104.99404, 39.75621]
}
};
L.geoJSON(geojsonFeature).addTo(map);
# all together now
At the risk of being overly verbose: the sum total of code required in a given markdown file is:
- some frontmatter
leaflet: true
- a line of html
<div id="map" style="height:400px"></div>
- a pair (or more, as required...) of script tags
<script src="/js/leafletMap.js"></script>
<script src="js/leafletExample/example.js"></script
and for the sake of completeness, here is what the my directories look like, including all the relevant files for this post (leaflet.md
)
├── src
│ ├── blog
│ │ ├── 2025
│ │ │ └── 04
│ │ │ └── leaflet.md
│ │ └── blog.json
│ ├── _includes
│ │ ├── layouts
│ │ │ ├── base.njk
│ │ │ ├── blog.njk
│ │ └── partials
│ │ ├── leafletHeader.njk
│ ├── js
│ │ ├── leafletExample
│ │ │ └── example.js
│ │ ├── leafletMap.js
# the result
# references
- this github discussion