Skip to content

Add LinkedIn Insight Tag and Dreamdata tracking#46

Merged
kev507 merged 13 commits into
mainfrom
claude/funny-swirles-1f0042
Jun 4, 2026
Merged

Add LinkedIn Insight Tag and Dreamdata tracking#46
kev507 merged 13 commits into
mainfrom
claude/funny-swirles-1f0042

Conversation

@kev507

@kev507 kev507 commented May 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Browser tracking scripts loaded on oxide.computer don't carry over to explorer.oxide.computer — each subdomain is its own scripting context and the consent cookie isn't shared across them. This installs the same LinkedIn Insight Tag and Dreamdata (cookied + cookieless) trackers the main site uses, gated by an equivalent cookie consent banner, so the 3D explorer contributes to LinkedIn ad attribution and Dreamdata B2B analytics.

The Dreamdata vendor IIFE snippets are copied byte-for-byte from oxide-computer/app/util/dreamdata.ts — they're two-stage bootstrappers (shim window.dreamdata as a method buffer, then inject the real SDK), so a plain <script src> would lose any calls made before the SDK lands.

Changes

  • src/util/tracking.ts — consent cookie helpers (hasAcceptedTracking, acceptTracking, rejectTracking, hasTrackingChoice)
  • src/util/dreamdata.ts — both Dreamdata IIFEs as const strings (verbatim)
  • src/components/CookiePopup.tsx — bottom-right banner with Reject/Accept; injects LinkedIn + cookied Dreamdata on accept, cookieless Dreamdata on mount for undecided users
  • src/App.tsx — mounts <CookiePopup /> at the top of MotionConfig (outside the pointer-events-none overlay container)
  • package.json / bun.lock — adds js-cookie and @types/js-cookie

Decisions (per author)

  • Consent cookie scoped per subdomain. Same cookie name (ox-accept-tracking) but no domain set, so accepting on the main site doesn't carry over here and vice versa. Independent consent decision per host.
  • Privacy link points to oxide.computer/privacy-policy externally. No new route added to this repo.
  • Production-only gating via import.meta.env.PROD. Dev (bun run dev) won't load any trackers.

What's not ported (and why)

  • Per-route dreamdata.page() tracking — rack-explorer is a single URL with state changes (selection, tours) that don't change the route. The snippet's built-in .page() covers the one true pageview.
  • trackFormSubmission and server-side LinkedIn lead conversion — no forms in this app.
  • 6sense — wasn't requested; easy to add later (one <script> tag + a _6si.push(['disableCookies', false]) in initTrackers).
  • Careers exclusion — no careers pages here.

Things to know before merging

  • One new oxlint error on CookiePopup.tsx (prefer-tag-over-role on <div role=\"dialog\">). Matches the source pattern in oxide-computer exactly. The codebase already has 4 pre-existing oxlint errors of similar nature; not addressing here to preserve byte-for-byte parity with the source. Easy to fix later with <dialog open> + a couple of CSS resets.

Test plan

  • bun install cleanly (lockfile is in the commit)
  • bun run build succeeds
  • bun run dev — confirm banner does NOT appear (dev mode)
  • bun run preview against the production build:
    • On first visit (fresh profile), banner appears bottom-right
    • Network tab shows a request to cdn.drda.io/.../dreamdata.cl.min.js (cookieless snippet auto-loaded)
    • Click Accept — banner dismisses, ox-accept-tracking=true cookie is set, Network tab shows new requests to snap.licdn.com/li.lms-analytics/insight.min.js, px.ads.linkedin.com/collect/?pid=6206948&fmt=gif, and cdn.dreamdata.cloud/.../dreamdata.min.js
    • Reload — no banner, cookied Dreamdata loads (not cookieless)
    • Clear cookies, reload, click Reject — banner dismisses, ox-accept-tracking=false, only cookieless Dreamdata loads, no LinkedIn requests

🤖 Generated with Claude Code

@vercel

vercel Bot commented May 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rack-explorer Ready Ready Preview Jun 4, 2026 9:55am

Request Review

@kev507

kev507 commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

Tightened the production gate so trackers don't fire on Vercel preview deployments (was flagged as a known issue in the PR body).

What changed (2e8deb8):

  • src/components/CookiePopup.tsx — gate is now import.meta.env.VITE_VERCEL_ENV !== 'production' instead of !import.meta.env.PROD. This mirrors the isProd semantics in oxide-computer/app/util/vars.ts, so the two subdomains gate the same way.
  • vite.config.tsdefine inlines process.env.VERCEL_ENV at build time. Vercel sets VERCEL_ENV automatically during the build step, so no Vercel project-config change is needed. Fails closed everywhere else (preview, local bun run build, undefined).

Test plan update: the step that says bun run preview should show the banner now needs VERCEL_ENV=production bun run build && bun run preview to simulate a real production build locally.

kev507 and others added 3 commits May 29, 2026 09:01
Browser tracking scripts on oxide.computer don't carry over to the
explorer.oxide.computer subdomain — each host is its own scripting
context and the consent cookie isn't shared. Port the same trackers
the main site uses (LinkedIn Insight Tag, Dreamdata cookied +
cookieless) along with the consent banner that gates them.

The Dreamdata IIFE snippets are copied byte-for-byte from oxide-
computer; the consent helpers and popup UI are adapted for a Vite
SPA (no SSR, no react-router, no careers exclusion, no forms).
Trackers only render when import.meta.env.PROD is true.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The repo went open-source on main while this branch was open. The
license-eye check requires the standard MPL-2.0 + Oxide copyright
header on all ts/tsx files; add it to the three new source files.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@david-crespo

Copy link
Copy Markdown
Contributor

Some things I'll be looking to fix here:

  1. I feel like bottom left is kind of an unusual location (button right is more common) but we can live with that
  2. Unfortunate interaction between the cookie modal and the What would you like to see? modal — the latter is on top and prevents interaction with the cookie modal. Doesn't feel good to be prompted by the cookie modal but be unable to click it. It would be better if you could click either one first and still be able to click the other. I guess ideally you wouldn't be confronted with two popups at the same time, but that seems harder to avoid.
  3. No cookie popup on screen width under 1000px.
image image

Mounting inside the left <nav> block left the popup trapped in three
ways: hidden under 1000px (nav has max-1000:hidden), blocked by the
landing modal (parent is z-10, modal is z-20), and tied to the left
column's flow layout. Move it back to a top-level MotionConfig child
and give it explicit `fixed bottom-4 left-4 z-100` so it floats above
everything and stays clickable while other modals are open.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@kev507

kev507 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

Pushed 0461b5b — lifted <CookiePopup /> back out of the left <nav> and gave it explicit fixed bottom-4 left-4 z-100. That fixes (2) z-index ordering vs the landing modal (was trapped under z-20) and (3) the mobile bug (was inheriting max-1000:hidden from the nav parent). Left it at bottom-left per your "we can live with that" on (1); happy to swap to bottom-right if you'd prefer.

@benjaminleonard

Copy link
Copy Markdown
Collaborator

Hmm lifting it out means it's not reflowing the left card to fit both. It's tricky because all four corners have important stuff that we don't want to obscure.

Restore Ben's mount inside the left <nav> so the popup reflows with
the Outline card and tour button instead of floating over them. Gate
the visible banner on !isLandingOpen so it appears only after the
user dismisses the landing modal — no more banner peeking out around
the modal, no overlap competition between two prompts. Trackers still
init via useEffect, so the cookieless pageview fires immediately on
load even while the banner is hidden.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@kev507

kev507 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Fair point — pushed 61c5b90 reverting to your sidebar mount so the nav reflows again. Handled the landing-modal overlap by gating the visible banner on !isLandingOpen so it appears sequentially after the modal is dismissed (no more peeking-out-around-modal). Trackers still init on mount via useEffect, so the cookieless pageview fires immediately even while the banner is hidden. One known limitation: mobile (<1000px) still doesn't see the banner since it's inside the max-1000:hidden nav — happy to add a separate mobile mount if you want.

@benjaminleonard

Copy link
Copy Markdown
Collaborator

Robot Kevin back off!

@kev507

kev507 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Standing down. 🫡

@benjaminleonard

Copy link
Copy Markdown
Collaborator
  1. I feel like bottom left is kind of an unusual location (button right is more common) but we can live with that
  2. Unfortunate interaction between the cookie modal and the What would you like to see? modal — the latter is on top and prevents interaction with the cookie modal. Doesn't feel good to be prompted by the cookie modal but be unable to click it. It would be better if you could click either one first and still be able to click the other. I guess ideally you wouldn't be confronted with two popups at the same time, but that seems harder to avoid.
  3. No cookie popup on screen width under 1000px.

2-3 fixed
1 agree in principle but looks funky with the contact sales CTA

@kev507 kev507 merged commit a42b9bb into main Jun 4, 2026
3 checks passed
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.

3 participants