flowsk.com
Ruby on Rails guide

First-party attribution for Ruby on Rails

Rails has everything the problem needs: a request cycle you own, cookies you can set server-side, background jobs for the ingestion, and a database that already knows who the user is. This is the stack where first-party attribution is genuinely easy — flowsk.com itself runs exactly this way.

Quick answer

Durable id (server-set) + client events (behaviour) + server events (truth) + dedup key

A concern sets the id cookie and records pageviews; model callbacks confirm identification and purchases. The one decision that matters on Ruby on Rails: who writes the visitor id. Written by JavaScript it lives 7 days in Safari; written by a server it lasts as long as you set it.

A `Trackable` concern with a `before_action` is all it takes: read or mint the id, set the cookie, enqueue the pageview job.

What Ruby on Rails gives you for free

Every stack has a natural advantage for first-party measurement. Use it before reaching for a tag manager.

`cookies.encrypted` / `cookies` in a `before_action` gives you a durable server-set id in three lines

Active Job keeps ingestion off the request cycle

Your models already know the email and the payment — the authoritative events are right there

What breaks on Ruby on Rails

The failure modes specific to this stack — the ones a generic install guide will not warn you about.

Turbo navigations are not document loads

Turbo Drive swaps the body without a full load, so a load-only pageview handler undercounts.

Fix  Listen for `turbo:load` as well as `DOMContentLoaded`.

Cookies in API-only controllers

`ActionController::API` has no cookie middleware by default.

Fix  Include `ActionController::Cookies` where you need the id.

Webhook idempotency

Payment webhooks retry. Without a de-duplication key you will record the same purchase several times.

Fix  Use the payment intent or subscription id as the dedup key.

Frequently asked questions

How do I set a durable first-party cookie in Rails?

In a `before_action`: `cookies[:_fsk_id] ||= { value: SecureRandom.uuid, expires: 2.years.from_now, httponly: true, same_site: :lax }`. Because Rails writes it in the response, Safari's 7-day JavaScript cap does not apply.

How do I record pageviews without slowing requests down?

Enqueue an Active Job from the `before_action` and return immediately. The ingestion happens off the request cycle.

How do I handle Turbo navigations?

Server-side pageviews already work — every Turbo Drive navigation is still a real GET to your server. That is one more reason the server-side approach is more accurate on Hotwire apps than a client tag.

How does flowsk dogfood this?

`Signals::Internal` sets the `_fsk_id` cookie server-side and calls the same public `Signals::Client` facade our customers' API calls go through — no shortcuts into the internals. See docs/attribution_product.md.

See the receipt for every conversion.

Flowsk Signals stitches the anonymous click to the email to the purchase — first-party, server-side, de-duplicated on a key you choose. One snippet, $29/mo, and a journey you can inspect event by event.