Handles short link redirects.
On each redirect:
- Look up link by domain + key
- Generate unique click_id
- Capture server-side data
- Check dedup cache
- Record click event if not duplicate
- Build redirect URL with link UTMs, passthrough params, and ga_id
- Fire :link_click hook (sync, crash-isolated)
- 302 redirect
Geo routing callback
When link.geo_targeting is non-empty, the redirect path consults the
configured :geo_routing_enabled_fn callback to decide whether to apply
country-based routing. The callback shape is {Module, :function} and
must accept a workspace_id :: Ecto.UUID.t().
Contract:
- MUST return a boolean.
- MUST NOT raise. A raise propagates and the redirect 500s — this is host-app misconfiguration that should be fixed, not silently swallowed. Cache lookups (e.g. via Nebulex) keep this hot.
Summary
Functions
Builds the final redirect URL by merging params in priority order
Handles a redirect for the given domain and key.
Functions
Builds the final redirect URL by merging params in priority order:
- Destination URL's existing query params (base)
- Link-level UTM params (stored on the link record)
- Short link request query params (passthrough from the clicked URL)
ga_id(always appended, highest priority)
Higher priority params overwrite lower. This means:
- Link UTMs override destination UTMs (marketer intent > default)
- Request passthrough overrides link UTMs (per-click override > per-link default)
ga_idis always present
When geo_map is provided AND the workspace has geo routing enabled via the
host-app :geo_routing_enabled_fn callback AND link.geo_targeting maps the
resolved country code to a non-empty URL, that URL replaces the device-
targeted/default destination before params are merged.
Handles a redirect for the given domain and key.