Today I implemented a small tracking feature to record when a mail_to link was clicked.

For this I used the sendBeacon API which performs a request without blocking the UI, making it perfect for tracking clicks.

The Stimulus controller for this was fairly straightforward, the awkward bit was to add the CSRF token

// app/javascript/controllers/call_to_action_controller.js
import { Controller } from "@hotwired/stimulus"  
  
// Connects to data-controller="call-to-action"  
export default class extends Controller {  
  static values = {  
    beaconUrl: String  
  }  
  track(event) {  
    const data = new FormData()  
    const token = document.querySelector('meta[name="csrf-token"]').content  
    data.append("authenticity_token", token);  
    navigator.sendBeacon(this.beaconUrlValue, data)  
  }  
}

then wired up to the ERB view

<%= mail_to('[email protected]',  
            "Email me",  
            data: {  
              controller: "call-to-action",  
              action: "click->call-to-action#track",  
              "call-to-action-beacon-url-value" => call_to_action_path  
            })

and a controller to handle the request.

class CallToActionsController < ApplicationController  
  def create  
    render status: :ok, json: {}  
  end  
end

There we have it, tracking Visitor clicks without blocking the UI.

I have implemented this with the field_test gem to track conversions with the controller action looking like this

class CallToActionsController < ApplicationController  
  def create  
    field_test_converted(:some_experiment)  
    render status: :ok, json: {}  
  end  
end