Skip to content

feat(statsig): marketing integration and SSR hero experiment#2918

Merged
HarshMN2345 merged 6 commits intomainfrom
feat/statsig-marketing-ssr
Apr 28, 2026
Merged

feat(statsig): marketing integration and SSR hero experiment#2918
HarshMN2345 merged 6 commits intomainfrom
feat/statsig-marketing-ssr

Conversation

@eldadfux
Copy link
Copy Markdown
Member

  • Add Statsig browser client, CTA forwarding, and stable user id (cookie + localStorage).
  • Evaluate hero description experiment on the server (statsig-node) to avoid client flash.
  • Document STATSIG_SERVER_SECRET in .env.example; extend CSP for Statsig.
  • Update mobile web app meta in app.html.

Made-with: Cursor

What does this PR do?

(Provide a description of what this PR does.)

Test Plan

(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work.)

Related PRs and Issues

(If this PR is related to any other PR or resolves any issue or related to any issue link all related PR and issues here.)

Have you read the Contributing Guidelines on issues?

(Write your answer here.)

- Add Statsig browser client, CTA forwarding, and stable user id (cookie + localStorage).
- Evaluate hero description experiment on the server (statsig-node) to avoid client flash.
- Document STATSIG_SERVER_SECRET in .env.example; extend CSP for Statsig.
- Update mobile web app meta in app.html.

Made-with: Cursor
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 27, 2026

Greptile Summary

This PR integrates Statsig for marketing analytics: a browser client (with session replay and web analytics plugins), a server-side experiment evaluation for the hero subtitle to avoid client flash, a stable user ID via cookie + localStorage, and CTA event forwarding from the existing analytics layer. Infrastructure wiring (Kubernetes secret, CI steps, CSP) is also included.

  • P1 — src/app.html: apple-mobile-web-app-capable was replaced with mobile-web-app-capable rather than adding both. mobile-web-app-capable is Android/Chrome-specific; without the Apple tag, iOS "Add to Home Screen" fullscreen mode is broken even though apple-mobile-web-app-status-bar-style and apple-mobile-web-app-title are still present.

Confidence Score: 4/5

Safe to merge after fixing the iOS PWA meta tag regression; all Statsig wiring is correct.

One P1 found: the removal of apple-mobile-web-app-capable breaks iOS Add to Home Screen fullscreen behavior. All other changes — CSP domains (confirmed legitimate), stable ID logic, SSR experiment evaluation, exposure logging, and Kubernetes secret management — are correct. No security issues identified.

src/app.html — the iOS PWA meta tag regression is the only blocking issue.

Important Files Changed

Filename Overview
src/app.html Changed apple-mobile-web-app-capable to mobile-web-app-capable, inadvertently breaking iOS Add to Home Screen fullscreen behavior while the remaining Apple meta tags remain.
src/lib/statsig/client.ts New browser Statsig client: dynamic imports, sync+async init, stable ID via cookie/localStorage, CTA event forwarding. Fallback ID generation in catch is now ephemeral (not 'anonymous'), addressing previous concern.
src/lib/statsig/hero-statsig.server.ts SSR experiment evaluation using getExperimentWithExposureLoggingDisabledSync; exposure logging deferred to client onMount. Module-level initPromise singleton handles concurrent server requests correctly.
src/routes/(marketing)/+page.server.ts New page server load: generates/reads stable ID cookie, evaluates hero experiment on SSR. httpOnly: false is correctly and explicitly commented.
src/hooks.server.ts CSP connect-src extended with Statsig domains; all domains including beyondwickedmapping.org are confirmed legitimate per Statsig's official CSP documentation.
src/routes/(marketing)/(components)/hero.svelte Accepts SSR-resolved heroSubtitle prop; onMount logs Statsig exposure after sync init. Adds min-height style to prevent layout shift between experiment variants.
deploy/website/templates/website.yaml Adds STATSIG_SERVER_SECRET env var from Kubernetes secret with optional: true, allowing graceful degradation when the secret doesn't yet exist.

Comments Outside Diff (1)

  1. src/app.html, line 684 (link)

    P1 apple-mobile-web-app-capable removed, breaking iOS Add to Home Screen

    mobile-web-app-capable is a Chrome/Android-specific hint. apple-mobile-web-app-capable is the separate iOS-only flag that enables fullscreen mode when users add the site to their home screen on Safari. Removing it means the two remaining Apple meta tags (apple-mobile-web-app-status-bar-style, apple-mobile-web-app-title) have no effect on iOS — the web app will open in a browser tab rather than fullscreen. Both tags should coexist:

Reviews (5): Last reviewed commit: "fix: allow missing statsig secret during..." | Re-trigger Greptile

Comment thread package.json Outdated
Comment thread src/lib/statsig/client.ts
Comment thread src/routes/(marketing)/+page.server.ts Outdated
Comment thread src/lib/statsig/client.ts
Comment on lines +29 to +43
* Evaluates `best_description` for SSR. Exposure is not logged here so the client can log the real view.
*/
export async function evaluateHeroDescriptionExperiment(
user: StatsigUser,
fallback: string
): Promise<string> {
const ready = await ensureStatsigServer();
if (!ready) return fallback;

try {
const experiment = Statsig.getExperimentWithExposureLoggingDisabledSync(
user,
STATSIG_EXPERIMENT_BEST_DESCRIPTION
);
return experiment.get('description', fallback) as string;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Experiment exposure is never logged

getExperimentWithExposureLoggingDisabledSync intentionally suppresses the impression log so the client can record it "on real view." However, no client-side code calls getExperiment(STATSIG_EXPERIMENT_BEST_DESCRIPTION) — the hero subtitle is passed directly from data.heroSubtitle without the browser SDK ever reading the experiment. With zero exposure logs, Statsig's dashboard will show no experiment traffic, goal metrics won't be attributed to the correct variant, and any statistical analysis will be invalid.

To fix this, after whenStatsigSyncReady() resolves in the hero component (or wherever the experiment result is consumed), call client.getExperiment(STATSIG_EXPERIMENT_BEST_DESCRIPTION) to log the exposure:

// e.g. in hero.svelte onMount, after Statsig is ready
whenStatsigSyncReady().then((client) => {
    if (client) client.getExperiment(STATSIG_EXPERIMENT_BEST_DESCRIPTION);
});

Comment thread deploy/website/templates/website.yaml
@HarshMN2345 HarshMN2345 merged commit dfa4ae7 into main Apr 28, 2026
6 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.

2 participants