Skip to content

Added Gift source attribution for gift-link signups#28896

Draft
kevinansfield wants to merge 1 commit into
mainfrom
gift-link-attribution-source
Draft

Added Gift source attribution for gift-link signups#28896
kevinansfield wants to merge 1 commit into
mainfrom
gift-link-attribution-source

Conversation

@kevinansfield

@kevinansfield kevinansfield commented Jun 25, 2026

Copy link
Copy Markdown
Member

no ref

Problem

Gift-link signups ({post_url}?gift={token}) don't show up as a distinct source in the Growth tab. When a reader of a gift-unlocked post signs up, they get attributed to whatever channel the link happened to be shared through — usually Direct when shared privately — so there's no way to see how many members a site gains via gift links.

Unlike gift subscriptions (a gifted paid subscription, which set member.status = 'gift'), gift links leave no server-side trace tying a signup to the gift: the gift-links service only validates tokens (no redemption — the redemption columns were dropped in 6.48), and the _gift token is surfaced to Tinybird for visit analytics only. So at signup the gift signal exists solely as the ?gift param on the unlocked post's URL in the browser — and the history recorder ignores it (it only reads ref/source/utm/attribution_id).

Change

Tag a validated ?gift visit with referrer source Gift (medium gift) in the frontend history recorder, so it flows through the existing referrer pipeline into members_created_events.referrer_source and shows up in the Growth sources breakdown. No new plumbing — it rides the same path every other channel (newsletter, Twitter, Ghost Explore) already uses.

  • The real referrer URL is preserved — only source/medium are overridden, so you still see where the reader actually came from.
  • An explicit ref/source/utm_source on the link still wins, so a site owner's own tagging isn't clobbered.
  • It composes with the existing content attribution: the signup is still attributed to the gifted post and carries source Gift.
  • Relies on a nice property of the existing gift flow: a valid token renders the post in place, while an invalid one is 301-stripped before render — so a ?gift param present when the recorder runs is always a genuine gift view.

Logic lives in a small, unit-tested helper (getGiftReferrer) in url-attribution.js; the IIFE in member-attribution.js just applies it.

Open for discussion 🧵

Opening as a draft to agree the details before polishing:

  • Override vs. defer to UTM — currently an explicit ref/source/utm_source on the link wins over Gift. Should Gift instead always win, on the basis that the gift is the more meaningful acquisition signal?
  • Canonical sourceGift is stored as a free-text source, so it shows in Growth but without first-class grouping/icon. Worth adding a canonical entry in @tryghost/referrer-parser's referrers.json?

Tests

  • getGiftReferrer unit tests in url-attribution.test.js: gift link, no gift, defers to explicit ref, defers to explicit utm_source, malformed URL.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 16d4afcb-2f2a-4dce-8849-575fcf34ec8c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gift-link-attribution-source

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Jun 25, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit e551dc1

Command Status Duration Result
nx run ghost:test:ci:integration ✅ Succeeded 2m 41s View ↗
nx run ghost:test:integration ✅ Succeeded 2m 18s View ↗
nx run ghost:test:legacy ✅ Succeeded 2m 52s View ↗
nx run ghost:test:e2e ✅ Succeeded 2m 7s View ↗
nx run-many --target=build --projects=tag:publi... ✅ Succeeded 3s View ↗
nx run @tryghost/admin:build ✅ Succeeded 5s View ↗
nx run-many -t test:unit -p ghost ✅ Succeeded 2s View ↗
nx run ghost:build:assets ✅ Succeeded 2s View ↗
Additional runs (2) ✅ Succeeded ... View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-06-25 12:32:22 UTC

@kevinansfield kevinansfield force-pushed the gift-link-attribution-source branch from e551dc1 to 101169f Compare June 25, 2026 12:19
no ref

- gift-link visits (`{post_url}?gift={token}`) unlock a single gated post; when
  the reader signs up they're attributed to whatever channel the link was shared
  through (usually Direct), so gift-derived signups are invisible as a distinct
  source in the Growth tab
- gift links leave no server-side trace tying a signup to the gift (unlike gift
  subscriptions, which set member.status='gift'): the gift-links service only
  validates tokens and the `_gift` token is surfaced to Tinybird for visit
  analytics only - so at signup the gift signal exists solely as the `?gift`
  param on the unlocked post's URL in the browser
- the history recorder ignores that param (it only reads ref/source/utm), so tag
  a `?gift` visit with referrer source 'Gift' (medium 'gift') there; it then
  flows through the normal referrer pipeline into
  members_created_events.referrer_source. The real referrer url is kept and an
  explicit ref/source/utm on the link still wins
- a valid token renders in place (invalid tokens are 301-stripped pre-render),
  so a `?gift` present when the recorder runs is always a genuine gift view
@kevinansfield kevinansfield force-pushed the gift-link-attribution-source branch from 101169f to bd86772 Compare June 25, 2026 12:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant