Skip to content

Label docs conversion links for Fullstory - #7067

Merged
jennifer-shehane merged 2 commits into
mainfrom
fullstory/conversion-links
Nov 7, 2026
Merged

jennifer-shehane merged 2 commits into
mainfrom
fullstory/conversion-links

Conversation

@jennifer-shehane

@jennifer-shehane jennifer-shehane commented Nov 7, 2026 •

Copy link
Copy Markdown
Member

Summary

Links in the docs that lead toward a possible sale or an existing Cypress Cloud account now carry a readable Fullstory label naming where on the page the link sits and where it goes. Examples: Docs Content - Pricing, Docs Footer - Product - Cloud, Docs Sidebar - Free Trial Guide. Each labeled link also records its utm_medium (its spot on the page) as a typed data-link-placement property. The Osano cookie banner labels now match www.cypress.io's.

Why

Fullstory recorded clicks from the docs as generated CSS-selector paths, so there was no way to see how many readers head from the docs to pricing, a trial, sales, a product page, or their Cloud account, or which spot on the page sent them.

docs.cypress.io, www.cypress.io, and Cypress Cloud all record into one Fullstory org, so this follows www.cypress.io's tracking-attribute rules (.agents/policies/tracking-attributes.md and the Gotcha section of .agents/architecture/fullstory.md in cypress-io/cypress.io):

  • Clicks are recorded with data-fs-element labels. This PR adds no trackEvent calls.
  • Labels are Title Case Surface - Action prose. The docs prefix every surface with Docs so their labels stay apart from www.cypress.io's own (Header - Sign Up).
  • data-fs-properties-schema maps data-link-placement to a typed string property.

The docs still never identify anyone; Cloud alone identifies signed-in users in this org.

What's labeled

plugins/fullstory-conversion-links.js classifies a link by destination, ignoring the query string and hash:

Destination Action
cloud.cypress.io/login Cloud Log In
cloud.cypress.io/signup Cloud Sign Up
www.cypress.io/contact Contact Sales
/cloud/get-started/free-trial (this site) Free Trial Guide
Any other cloud.cypress.io path, on.cypress.io/cloud, on.cypress.io/dashboard Open Cloud
www.cypress.io/pricing Pricing
www.cypress.io/accessibility, /app, /cloud, /features, /ui-coverage Product - Accessibility, App, Cloud, Features, UI Coverage
www.cypress.io links with utm_content=Request trial Request Trial
www.cypress.io/savings-calculator Savings Calculator

cypress.io and www.cypress.io are treated the same, since 18 pricing links use the apex domain and it redirects to www.

The surface comes from where the link renders: Docs Content, Docs Navbar, Docs Sidebar (What's New included), Docs Footer, or Docs Announcement.

How the labels get there

All labels are in the built HTML, so nothing depends on when a part of the page mounts:

  • Markdown links: a rehype plugin, plugins/fullstory-conversion-links-rehype.js, labels them at build time. It never overwrites an existing data-fs-element.
  • Components and config: the footer and navbar items in docusaurus.config.js, plus SidebarLink, What's New, Btn, ProductHeading, Icon, and Badge, add the attributes in source.
  • Nested elements: Fullstory reports a click on a nested element with its own classes (inline code, an icon) under that element, not the link. One rule in src/css/custom.scss, a[data-link-placement] * { pointer-events: none; }, sends those clicks to the labeled link. That's www.cypress.io's other documented fix for the same behavior.

Across the built site, 1,926 links get a label:

Label Links Pages
Docs Content - Contact Sales 1 1
Docs Content - Cloud Sign Up 11 11
Docs Content - Free Trial Guide 4 4
Docs Content - Open Cloud 109 34
Docs Content - Pricing 90 51
Docs Content - Product - Accessibility 40 39
Docs Content - Product - App 221 221
Docs Content - Product - Cloud 1 1
Docs Content - Product - UI Coverage 44 37
Docs Content - Request Trial 6 5
Docs Content - Savings Calculator 4 4
Docs Footer - Product - Accessibility 338 338
Docs Footer - Product - Cloud 338 338
Docs Footer - Product - Features 338 338
Docs Footer - Product - UI Coverage 338 338
Docs Sidebar - Free Trial Guide 43 43

No navbar, announcement, or What's New link leads to one of these destinations today, so those surfaces have no labeled links yet.

Osano label changes

These match www.cypress.io's, so one funnel covers the consent banner on both sites. Fullstory funnels built on the old names need repointing.

Button Old label New label
Accept Cookie Consent - Accept Cookie Consent - Accept All
Deny all, deny Cookie Consent - Reject Cookie Consent - Deny All
Manage Cookie Consent - Manage Preferences unchanged
Close Cookie Consent - Dismiss unchanged

The footer's Cookie Consent - Open Preferences is unchanged.

Notes for reviewers

  • Why build time: the first commit labeled Markdown links from a client module after each route change. That missed links that mount later, such as the mobile sidebar drawer, which renders only when it's opened. The second commit replaces it with the rehype plugin and in-source labels, and removes the client module.
  • Docs Content - Product - App: on App pages, ProductHeading renders an empty link with no badge, so those 221 labeled links have nothing a reader can click. Dropping that link in the component may be worth a follow-up.
  • Announcement bar: its content is a raw HTML string, so nothing labels its links automatically. A comment in docusaurus.config.js says what a future conversion link there needs.
  • Destinations deliberately left unclassified (they look conversion-related but weren't in scope):
    • on.cypress.io/accessibility-trial, on.cypress.io/ui-coverage-trial (one each)
    • on.cypress.io/accessibility-demo-video (1), on.cypress.io/ui-coverage-demo-video (2)
    • on.cypress.io/dashboard/organizations (1)
    • www.cypress.io/support (338, footer)
    • www.cypress.io/releases/cloud, www.cypress.io/roadmap/cloud, and the bare www.cypress.io (one each)
  • Not verified: that Fullstory reports clicks under these labels. That needs a build with a real FULLSTORY_ORG_ID and Analytics consent, so a look at a deploy preview would confirm it.

Checks run

  • npm run typecheck: passed.
  • npm run test:plugins: passed, including 51 tests for the classifier and rehype plugin (npm run test:fullstory-conversion-links).
  • npm run build with FULLSTORY_ORG_ID unset: passed.
  • cypress/e2e/fullstory_conversion_links.cy.ts 6/6 and cypress/e2e/osano.cy.ts 4/4, against npm run serve in Chrome for Testing.
    • The new spec reads server-rendered HTML for content, footer, and sidebar links.
    • In the browser it covers the mobile drawer, client-side navigation, and a click on a button's icon. With the pointer-events rule overridden, that click lands on the SVG path instead of the link, so the test catches a regression.
  • Classifier run over all 69,160 a[href] in dist/: every one of the 1,926 conversion links carries the expected label in the built HTML.
  • No .mdx files changed, so there were no code examples to run.

Generated by Claude Code


Note

Medium Risk
Touches site-wide link rendering and analytics attribution across ~1,900 links; Osano label renames can break existing Fullstory funnels until repointed.

Overview
Adds Fullstory data-fs-element labeling for docs links that point at pricing, trials, Cloud sign-in/up, product pages, and similar conversion destinations, using the shared Docs <Surface> - <Action> naming convention and a typed data-link-placement property from each link’s utm_medium.

Implementation: New plugins/fullstory-conversion-links.js classifies hrefs and emits attributes; a rehype plugin labels Markdown/MDX links at build time; withConversionLabels wraps navbar/footer config; React link surfaces (Badge, Btn, ProductHeading, sidebar, What’s New, etc.) spread the same helper. a[data-link-placement] * { pointer-events: none; } keeps clicks on nested icons/code attributed to the parent link.

Osano consent button labels are renamed to match www.cypress.io (Accept All, Deny All), with Cypress specs asserting exact label strings.

Tests: Vitest for the classifier and rehype plugin; new fullstory_conversion_links.cy.ts for SSR HTML, client nav, mobile drawer, and click targeting.

Reviewed by Cursor Bugbot for commit be68ea5. Bugbot is set up for automated code reviews on this repo. Configure here.

Fullstory showed clicks from the docs only as generated CSS-selector paths,
so there was no way to see how many readers leave the docs for pricing, a
trial, sales, a product page, or their Cypress Cloud account, or which spot
on the page sent them.

Each such link now carries a data-fs-element label, "<Surface> - <Action>"
(for example "Docs Content - Pricing" or "Docs Footer - Product - Cloud"),
plus its utm_medium as a typed data-link-placement property. This follows
www.cypress.io's tracking-attribute convention, since both sites and Cloud
record into one Fullstory org. The "Docs" surface prefix keeps these
labels apart from www.cypress.io's own.

- plugins/fullstory-conversion-links.js classifies a link by destination
  and builds the attributes. docusaurus.config.js uses it for the footer
  and navbar, and What's New, Btn, and ProductHeading use it in source.
- A new client module labels Markdown links where they render, on load and
  after each route change. It never overwrites an existing label.
- Every descendant of a labeled link gets the same attributes, because
  Fullstory reports a click on nested inline code or an icon under that
  element rather than the link.
- The Osano banner labels now match www.cypress.io's ("Accept All",
  "Deny All"), so one funnel covers the consent banner on both sites.

No trackEvent calls are added, and the docs still never identify visitors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WUv8r1dRvperh82bP9Tx1B
The client module labeled links two frames after each route change, so a
link rendered later went unlabeled. The mobile sidebar drawer, for one,
mounts only when opened, so its Free Trial Guide link was never labeled on
phones.

Labels now come with the markup itself:

- A rehype plugin labels Markdown links when the docs are built, so they
  are in the server-rendered HTML and every client render.
- SidebarLink, Icon, and Badge label their own links, alongside Btn,
  ProductHeading, What's New, and the footer and navbar config.
- A pointer-events rule in custom.scss sends clicks on a link's nested
  elements (inline code, an icon) to the labeled link, so nothing has to
  copy the label onto them. This is www.cypress.io's other documented fix
  for the same Fullstory behavior.

The client module and the descendant-labeling helper are removed. The e2e
spec now checks server-rendered HTML for most links. In the browser it
covers the mobile drawer, client-side navigation, and a click on a
button's icon, which fails if the pointer-events rule is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WUv8r1dRvperh82bP9Tx1B
@jennifer-shehane
jennifer-shehane merged commit 1c5134c into main Nov 7, 2026
21 checks passed
@jennifer-shehane
jennifer-shehane deleted the fullstory/conversion-links branch November 7, 2026 21:01
@cypress

cypress Bot commented Nov 7, 2026

Copy link
Copy Markdown

cypress-documentation    Run #2806

Run Properties:  status check passed Passed #2806  •  git commit 2af0c19563 ℹ️: Merge be68ea57fa9708b2e6e2a46c7ebbc66323b152f1 into 8d82546d64f56f8552b1f2cba6e2...
Project cypress-documentation
Branch Review fullstory/conversion-links
Run status status check passed Passed #2806
Run duration 02m 19s
Commit git commit 2af0c19563 ℹ️: Merge be68ea57fa9708b2e6e2a46c7ebbc66323b152f1 into 8d82546d64f56f8552b1f2cba6e2...
Committer Jennifer Shehane
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 443
View all changes introduced in this branch ↗︎
UI Coverage  32.91%
  Untested elements 738  
  Tested elements 26  
Accessibility  98.93%
  Failed rules  2 critical   5 serious   4 moderate   1 minor
  Failed elements 73  

@cypress

cypress Bot commented Nov 7, 2026

Copy link
Copy Markdown

cypress-documentation    Run #2807

Run Properties:  status check passed Passed #2807  •  git commit 1c5134c479: Label docs conversion links for Fullstory (#7067)
Project cypress-documentation
Branch Review main
Run status status check passed Passed #2807
Run duration 02m 06s
Commit git commit 1c5134c479: Label docs conversion links for Fullstory (#7067)
Committer Jennifer Shehane
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 1
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 443
View all changes introduced in this branch ↗︎
UI Coverage  32.82%
  Untested elements 738  
  Tested elements 25  
Accessibility  98.91%
  Failed rules  2 critical   6 serious   4 moderate   1 minor
  Failed elements 152  

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.

2 participants