leaflet.js on Rails 7 with esbuild + stimulus.js

A quick tutorial for using leaflet with on a Rails 7 application using stimulus.

Knerav Kodolikar
3 min readDec 31, 2022

Introduction

In this short tutorial, we will configure a Rails 7 application to use leaflet.js using a stimulus controller. If a project you’re working on requires you to have the ability to display or grab location information, leaflet.js can help you get started with rendering a basic map quickly and efficiently. Javascript in Rails has been an issue of contention for a quite some time, but with Rails 7 shipping with Stimulus out of the box, I believe that it has become easier to keep track of your JS within the application.

Note: I’m using a Rails application with esbuild as the javascript bundler, the following instructions have been written with this setup.

Application Setup

Skip this and the next step if you already have an application up and running. I’ll be using Tailwind for my CSS and Postgresql for my database (We can then enable postGIS, but that is out of the scope of this tutorial). We can create a Rails 7 application with the above specifications using the following command in your terminal:

rails new test_leaflet_application -j esbuild -d postgresql -c tailwind

Navigate to your application and we’re ready to get started!

Views & Routing

Let’s create a pages controller with a homepage action:

rails g controller Pages homepage

One can use ‘g’ as shorthand for ‘generate’. Navigate to the views/pages folder and create homepage.html.erb. We’ll use this view to render our map.

Leaflet.js Setup

To enable leaflet’s ready-to-go functions we must configure it’s pre-written JS and CSS. First, we add the following to our application layout (application.html.erb) file:

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css"
integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI="
crossorigin=""/>

To add leaflet’s JS in our application, you could either add leaflet’s JS through their CDN, or if you’re running esbuild include it as an NPM package:

npm i leaflet

Map View and Controller Setup

I am using a stimulus controller to house the JS that renders the map for two reasons. Firstly because through this method I can render multiple maps with the same JS code by defining multiple targets (we’ll get to this later), secondly, I find the stimulus approach to enhancing your HTML views to be quite appealing and I am willing to try the Rails way of doing things.

To render the map we need to create a div which we will use to access our stimulus controller and set a target as well:

<div data-controller="maps">
<div data-maps-target="container" class="h-[25rem] w-auto"></div>
</div>

The data-controller DOM element links this, and every div within it, to the “maps” stimulus controller, through which we can use data-maps-target to select that div as our target. Do not forget to add a height and width to the map div, I am using Tailwind but a simple style declaration will work. Next, let’s generate the maps stimulus controller (you can name this controller anything, but don’t forget to reference it properly in your HTML):

rails g stimulus Maps

This will generate maps_controller.js in the javascript folder. Navigate to the controller and now we can begin initialising the map. First, we have to import leaflet’s JS functions from our NPM package. Then, we define our target and, lastly, initialise and render the map in the defined target. Your maps controller should look like this:

import { Controller } from "@hotwired/stimulus"
import L from "leaflet"

// Connects to data-controller="maps"
export default class extends Controller {
static targets = ["container"]

connect() {
var map = L.map(this.containerTarget).setView([12.9716, 77.5946], 11.5);

L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
}

disconnect() {
this.map.remove();
}
}

The code to initialise the map has been referenced from the leaflet.js quick start guide (Where you will also find their CDN links). With this, you should have a map up and running in your views and should look something like the image below, following leaflet’s guide I was able to customise it’s look and functions as well.

Hope you found this guide useful!

Default Open Street map rendered successfully

--

--

Knerav Kodolikar
Knerav Kodolikar

Written by Knerav Kodolikar

Navigating urban governance issues using a multidisciplinary toolkit.

Responses (1)