Recently I have been struggling when trying to embed a leaflet map created with RStudio on my blog, hosted in GitHub via Jekyll (Spoiler: I succeeded ). In my case, I use the Beautiful Jekyll implementation created by @daattali.

So I decided to spend a good amount of time shaping this small tutorial. It can be longer than expected but after doing this process 3 or 4 times it becomes almost trivial.

Index

  1. What to include

  2. Where to include

  3. Creating the leaflet map

  4. Set up the YAML front matter

  5. Modifying the .md file

  6. Publish your post

Gallery: Size of a leaflet map

Ready? Let’s go!

The GitHub/Jekyll part

The first step is to install the requested libraries in your GitHub page. As Jekyll basically transforms markdown into html, this step is a matter of what to include and where in your own repository.

1. What to include  

This part is not really hard. When having a look to the source code of Leaflet for R site it can be seen this chunk:

<head>
  <!--code-->
  
  <script src="libs/jquery/jquery.min.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link href="libs/bootstrap/css/flatly.min.css" rel="stylesheet" />
  <script src="libs/bootstrap/js/bootstrap.min.js"></script>
  <script src="libs/bootstrap/shim/html5shiv.min.js"></script>
  
  ...
  <!--more libraries-->
  ...
  
  <link href="libs/rstudio_leaflet/rstudio_leaflet.css" rel="stylesheet" />
  <script src="libs/leaflet-binding/leaflet.js"></script>
  
  <!--code-->
</head>

So now we have it! The only thing to remember is that we need to load the libraries from the leaflet server (https://rstudio.github.io/leaflet), meaning that we have to prepend that url to the libraries in our installation:

  <script src="https://rstudio.github.io/leaflet/libs/jquery/jquery.min.js"></script>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link href="https://rstudio.github.io/leaflet/libs/bootstrap/css/flatly.min.css" rel="stylesheet" />
  
  ...
  <!--more libraries-->
  ...
  
  <link     href="https://rstudio.github.io/leaflet/libs/rstudio_leaflet/rstudio_leaflet.css" rel="stylesheet" />
  <script src= "https://rstudio.github.io/leaflet/libs/leaflet-binding/leaflet.js"></script>

You can have a look of my implementation on ./_includes/leaflet.html.

2.Where to include  

This a little bit more complicated, depending on the structure of your Jekyll template. The code chunk should be included in the <head> section of your page, so you would need to find where to put it. In the case of Beautiful Jekyll it is on ./_includes/head.html.

So now you just have to paste in the <head> the code that you got on step 1.

Pro tip: For a better performance of the site, include these libraries only when you need it. In my case, I added a custom variable in my YAML front matter for those posts with a leaflet map, leafletmap: true. Go to step 4 for a working example.

The RStudio part

3. Creating the leaflet map  

Now it’s time to create a leaflet map with RStudio. I just keep it simple for this post, so I took the first example provided in Leaflet for R - Introduction

library(leaflet)

m <- leaflet() %>%
  addTiles() %>%  # Add default OpenStreetMap map tiles
  addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
m  # Print the map

It is assumed that you are creating a post with RStudio, so the code presented above should be embedded in an .Rmd file.

4. Set up the YAML front matter  

Before knitting your .Rmd, you have to set up the YAML front matter. Here it is essential to set up the option always_allow_html: yes, as well as output: github_document. As an example, this post was created with the front matter:

layout: post
title: Leaflet, R, Markdown, Jekyll and GitHub
subtitle: Make it work in 6 steps - a short tutorial
tags: [R,leaflet,Jekyll, html, maps]
linktormd: true
leafletmap: true
always_allow_html: yes
output: github_document

We are almost there! Now “Knit” your code and get the corresponding .mdfile.

The Markdown part

5. Modifying the .md file  

Update: Depending on how you render your file this step may not be neccesary.

Have a look to the .md code that you have just created. Although not displayed in the preview, you can see in the file itself a chunk that looks like this:

<!--html_preserve-->

  <script type="application/json" data-for="htmlwidget-7ab57412f7b1df4d5773">
    {"x":{"options":
      ...
      "jsHooks":[]}
  </script>
<!--/html_preserve-->

Actually that chunk is your leaflet map, created with RStudio. You can’t see it now because you are previewing a markdown file in your local PC, and the libraries installed in step 1 are installed on GitHub, but we would solve it later.

Now you just need to paste this piece of code before that chunk:

<!--html_preserve-->
<div id="htmlwidget-7ab57412f7b1df4d5773" style="width:100%;height:216px;" class="leaflet html-widget"></div>
  <script type="application/json" data-for="htmlwidget-7ab57412f7b1df4d5773">
  ...

Warning: Be sure that the widget id (7ab57412f7b1df4d5773 in the example) is the same in the <div> and in the <script> part. If not your map would not load.

The style= "width: 100%; height: 216px;" part controls the actual size of the leaflet widget. In this case, the map would adapt to the width of the page with a fixed height of 216px. I put some examples at the end of the post of different size options so you can have a look and see which one is more suitable for your needs.

6. Publish your post  

Now you just have to publish your post as usual!! If everything has been properly set, when Jekyll builds your post it would include the libraries in the header and make the magic happens, just like this:

Warning: Have you checked the YAML front matter of your .md file? Have another look, specially if you have followed my Pro tip.



For a complete understanding of this section it is recommended to access it on multiple devices (you can easily simulate a bunch of them with Google Chrome, right-click “Inspector”, and using the “Device Mode”), so you can see the different behavior on different screens.

Let’s start creating a new leaflet map:  

map <- leaflet(options = leafletOptions(minZoom = 1.25, maxZoom = 8)) %>%
  addTiles() %>%
  setMaxBounds(-200, -90, 200, 90) %>%
  setView(-3.56948,  40.49181, zoom = 3) %>%
  addEasyButton(easyButton(
    icon = "fa-globe",
    title = "World view",
    onClick = JS("function(btn, map){ map.setZoom(1.25); }")
  )) %>%
  addEasyButton(easyButton(
    icon = "fa-crosshairs",
    title = "Locate Me",
    onClick = JS("function(btn, map){ map.locate({setView: true}); }")
  ))

Fixed size

With these examples you can see how to control the absolute size of the leaflet map. The disadvantage of this method is that the size would be fixed for all the devices, so maps sized for smartphones or tables wouldn’t look as nice in laptops, etc. and vice versa. To test it, just zoom in and out this post from your smartphone and have a look on how Example 1 looks like compared with the rest of maps.


Example 1: 640x480px

Fixed size in pixels. By default in my machine is "width: 640px; height: 480px;", so if i want to keep it the next <div> should be included:

<div id="htmlwidget-xxxxxxxxxxxxxxxx" style="width:640px; height:480px;" class="leaflet html-widget"></div>

Note that this leaflet map could be wider than some screens (specially smartphones) and it would mess a little bit the overall apearance of this post.

Example 2: 100x300px

Let’s go narrow and long with "width: 100px;height: 300px;":

<div id="htmlwidget-xxxxxxxxxxxxxxxx" style="width:100px; height:300px;" class="leaflet html-widget"></div>

Dynamic size

Recommended option. These maps would adapt to the width of your screen, no matter what device you are using. Additionally, you can adapt the aspect ratio to different flavours.


Example 3: 16:9 aspect ratio

Most common aspect ratio for televisions and computer monitors. Note that the value 56.25% is just the result of dividing 9 by 16.

<div id="htmlwidget-xxxxxxxxxxxxxxxx" style="position: relative; width: 100%;padding-top: 56.25%;" class="leaflet html-widget"></div>

Example 4: 4:3 aspect ratio

“Old” standard for televisions and computer monitors.

<div id="htmlwidget-xxxxxxxxxxxxxxxx" style="position: relative; width: 100%;padding-top: 75%;" class="leaflet html-widget"></div>

Example 5: 4:1 aspect ratio (Polyvision)

Rare aspect ratio (also known as Polyvision) used only on the 1927 silent french film Napoléon. It is unlikely that you use this one but illustrates an extreme aspect ratio.

<div id="htmlwidget-xxxxxxxxxxxxxxxx" style="position: relative; width: 100%;padding-top: 25%;" class="leaflet html-widget"></div>

Example 6: 10:7 aspect ratio

Suitable for all devices. My personal choice.

<div id="htmlwidget-xxxxxxxxxxxxxxxx"  style="position: relative; width: 100%;padding-top: 70%;" class="leaflet html-widget"></div>

Pro tip: Try to use dynamic sizing unless you really need a fixed width. I did some tests and 10:7 (70%) is a good ratio for overall purposes, specially if your leaflet map is intended to show a full world map. In that case, combine it with minZoom, maxZoom and setMaxBounds options (see example) for optimal results.