-
Notifications
You must be signed in to change notification settings - Fork 897
fix(marketing): prevent env validation from blocking React hydration #3388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Server | ||
| BETTER_AUTH_SECRET= | ||
| RESEND_API_KEY= | ||
| KV_REST_API_URL= | ||
| KV_REST_API_TOKEN= | ||
| STRIPE_SECRET_KEY= | ||
| STRIPE_WEBHOOK_SECRET= | ||
| STRIPE_PRO_MONTHLY_PRICE_ID= | ||
| STRIPE_PRO_YEARLY_PRICE_ID= | ||
| SLACK_BILLING_WEBHOOK_URL= | ||
| SENTRY_AUTH_TOKEN= | ||
| ANTHROPIC_API_KEY= | ||
|
|
||
| # Client | ||
| NEXT_PUBLIC_API_URL= | ||
| NEXT_PUBLIC_WEB_URL= | ||
| NEXT_PUBLIC_POSTHOG_KEY= | ||
| # Defaults to https://us.posthog.com if not set | ||
| NEXT_PUBLIC_POSTHOG_HOST=https://us.posthog.com | ||
| NEXT_PUBLIC_SENTRY_DSN_MARKETING= | ||
| NEXT_PUBLIC_SENTRY_ENVIRONMENT= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,41 +5,49 @@ import posthog from "posthog-js"; | |
| import { env } from "@/env"; | ||
| import { ANALYTICS_CONSENT_KEY } from "@/lib/constants"; | ||
|
|
||
| posthog.init(env.NEXT_PUBLIC_POSTHOG_KEY, { | ||
| api_host: "/ingest", | ||
| ui_host: "https://us.posthog.com", | ||
| defaults: "2025-11-30", | ||
| capture_pageview: "history_change", | ||
| capture_pageleave: true, | ||
| capture_exceptions: true, | ||
| debug: false, | ||
| cross_subdomain_cookie: true, | ||
| persistence: "cookie", | ||
| persistence_name: POSTHOG_COOKIE_NAME, | ||
| disable_session_recording: true, | ||
| loaded: (posthog) => { | ||
| posthog.register({ | ||
| app_name: "marketing", | ||
| domain: window.location.hostname, | ||
| }); | ||
| try { | ||
| posthog.init(env.NEXT_PUBLIC_POSTHOG_KEY, { | ||
| api_host: "/ingest", | ||
| ui_host: "https://us.posthog.com", | ||
| defaults: "2025-11-30", | ||
| capture_pageview: "history_change", | ||
| capture_pageleave: true, | ||
| capture_exceptions: true, | ||
| debug: false, | ||
| cross_subdomain_cookie: true, | ||
| persistence: "cookie", | ||
| persistence_name: POSTHOG_COOKIE_NAME, | ||
| disable_session_recording: true, | ||
| loaded: (posthog) => { | ||
| posthog.register({ | ||
| app_name: "marketing", | ||
| domain: window.location.hostname, | ||
| }); | ||
|
|
||
| const consent = localStorage.getItem(ANALYTICS_CONSENT_KEY); | ||
| if (consent === "declined") { | ||
| posthog.opt_out_capturing(); | ||
| } | ||
| }, | ||
| }); | ||
| const consent = localStorage.getItem(ANALYTICS_CONSENT_KEY); | ||
| if (consent === "declined") { | ||
| posthog.opt_out_capturing(); | ||
| } | ||
| }, | ||
| }); | ||
| } catch (e) { | ||
| console.warn("PostHog failed to initialize", e); | ||
| } | ||
|
Comment on lines
+8
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The PR's QA checklist claims that removing Line 5 ( To match the documented QA behavior, Without this, QA checklist item #3 will fail when tested, and the same silent hydration block described in the PR could recur if the PostHog key var is ever absent from a deployment. |
||
|
|
||
| Sentry.init({ | ||
| dsn: env.NEXT_PUBLIC_SENTRY_DSN_MARKETING, | ||
| environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT, | ||
| enabled: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT === "production", | ||
| tracesSampleRate: | ||
| env.NEXT_PUBLIC_SENTRY_ENVIRONMENT === "production" ? 0.1 : 1.0, | ||
| replaysSessionSampleRate: 0, | ||
| replaysOnErrorSampleRate: 0, | ||
| sendDefaultPii: true, | ||
| debug: false, | ||
| }); | ||
| try { | ||
| Sentry.init({ | ||
| dsn: env.NEXT_PUBLIC_SENTRY_DSN_MARKETING, | ||
| environment: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT, | ||
| enabled: env.NEXT_PUBLIC_SENTRY_ENVIRONMENT === "production", | ||
| tracesSampleRate: | ||
| env.NEXT_PUBLIC_SENTRY_ENVIRONMENT === "production" ? 0.1 : 1.0, | ||
| replaysSessionSampleRate: 0, | ||
| replaysOnErrorSampleRate: 0, | ||
| sendDefaultPii: true, | ||
| debug: false, | ||
| }); | ||
| } catch (e) { | ||
| console.warn("Sentry failed to initialize", e); | ||
| } | ||
|
|
||
| export const onRouterTransitionStart = Sentry.captureRouterTransitionStart; | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1:
try/catchdoes not protect against a missingNEXT_PUBLIC_POSTHOG_KEY. Theimport { env } from "@/env"on line 5 runs at module evaluation time — before thistryblock is reached. IfNEXT_PUBLIC_POSTHOG_KEYis absent,createEnvthrows during the import, killing hydration exactly like the original bug. To actually guard against this, either makeNEXT_PUBLIC_POSTHOG_KEYoptional with a default/guard inenv.ts, or lazily accessenvinside thetryblock (e.g., via a dynamic import or deferred access pattern).Prompt for AI agents