Skip to content

feat: serve welcome at root and dashboard at /dashboard#4307

Merged
koala73 merged 6 commits into
mainfrom
codex/welcome-home-dashboard-route
Jun 16, 2026
Merged

feat: serve welcome at root and dashboard at /dashboard#4307
koala73 merged 6 commits into
mainfrom
codex/welcome-home-dashboard-route

Conversation

@koala73

@koala73 koala73 commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • Serve the public welcome landing page from / and permanently redirect legacy /welcome to root.
  • Move the existing SPA dashboard shell to /dashboard, including canonicals, sitemap, Link headers, checkout returns, and dashboard CTAs.
  • Redirect likely signed-in welcome visitors to /dashboard after lazy Clerk verification, while keeping anonymous visitors on the landing page without eagerly loading auth.

Testing

  • npm run lint in pro-test
  • npm run build in pro-test
  • node --test tests/deploy-config.test.mjs
  • TMPDIR=/tmp node --import tsx --test tests/checkout-return-discriminant.test.mts tests/deploy-config.test.mjs
  • npm run typecheck
  • npm run typecheck:api
  • Normal git push pre-push hook passed, including typechecks, server handler tests, changed tests, edge function tests, pro-test bundle freshness, and version sync.

Post-Deploy Monitoring & Validation

  • Validation window: first 60 minutes after Vercel production deployment; owner: on-call/release owner.
  • Healthy signals: / returns the welcome HTML, /dashboard returns the dashboard shell, /welcome returns a permanent redirect to /, and checkout success returns land on /dashboard?wm_checkout=success before client cleanup.
  • Watch Vercel function/static routing logs for unexpected 404/500s on /, /dashboard, /welcome, /pro, /pro/welcome.html, and /index.html.
  • Watch Sentry for new errors containing WelcomeApp, ensureClerk, wm_checkout, DASHBOARD_CHECKOUT_SUCCESS_URL, or embed=pro-preview.
  • Check search/SEO smoke manually after deploy: canonical on / is https://www.worldmonitor.app/, canonical on /dashboard is https://www.worldmonitor.app/dashboard, and sitemap contains /dashboard but not /welcome.
  • Rollback trigger: elevated 404/500s on / or /dashboard, logged-in users stuck on root, checkout users failing to reach the dashboard success state, or CSP violations blocking dashboard scripts. Mitigation: revert this PR or restore prior Vercel rewrites/canonicals while investigating.

@vercel

vercel Bot commented Jun 13, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
worldmonitor Ready Ready Preview, Comment Jun 16, 2026 12:48pm

Request Review

@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR moves the public welcome/marketing page to serve from / (previously /welcome) and relocates the SPA dashboard shell to /dashboard (previously /), with a permanent 301 redirect from /welcome to /. A new routes.ts constants file centralises all dashboard URLs, replacing ~8 scattered hardcoded strings across the pro-test and main SPA.

  • Vercel routing: explicit /welcome.html and /dashboardindex.html rewrites are added before the SPA catch-all; the /welcome redirect is added to redirects; the Cache-Control + Link headers move from the /welcome rule to a new /dashboard rule.
  • Checkout URLs: all three returnUrl/redirectTo sites in pro-test, APP_CHECKOUT_BASE_URL in the main SPA, and buildCheckoutLaunchUrl are updated to https://worldmonitor.app/dashboard; a new client-side auth check in WelcomeApp.tsx lazily redirects signed-in visitors from / to /dashboard using the Clerk session heuristic.
  • SEO/meta: canonicals, hreflang, OG/Twitter URLs, JSON-LD, and sitemap entries are all updated consistently; meta-tags.ts is refactored to derive CANONICAL_URL and PUBLIC_ORIGIN separately from variant-meta.ts.

Confidence Score: 4/5

The routing refactor is structurally sound and well-tested, but the auth redirect in WelcomeApp strips query params, breaking checkout return handling for any payment sessions active at the moment of deployment.

The URL migration is thorough and consistent across all 43 files — constants centralised, SEO meta updated, rewrites/redirects/headers aligned, and test assertions rewritten. The one gap is in WelcomeApp.tsx: window.location.replace(DASHBOARD_PATH) discards the current URL query string. Any checkout session initiated before deployment whose payment completes after and returns to /?wm_checkout=success would get redirected to bare /dashboard, dropping the param that triggers the post-checkout success state. The window is bounded by in-flight sessions at deploy time, and the developer's monitoring plan covers it, but the fix is a one-liner.

pro-test/src/WelcomeApp.tsx — the auth redirect needs to forward window.location.search to the target URL.

Important Files Changed

Filename Overview
vercel.json Routing refactor: adds /welcome.html and /dashboardindex.html rewrites, redirects /welcome/, moves Cache-Control + Link headers from /welcome to /dashboard, updates CSP with two new script hashes. Stale `
pro-test/src/WelcomeApp.tsx New lazy-auth redirect: heuristically checks for a Clerk session via cookies/localStorage, dynamically imports the checkout service, and replaces the page with /dashboard for signed-in users. The redirect strips all query params from the current URL, which breaks in-flight checkout sessions returning to /?wm_checkout=success after deployment.
pro-test/src/routes.ts New file centralising route/URL constants — DASHBOARD_PATH, DASHBOARD_URL, DASHBOARD_CHECKOUT_SUCCESS_URL, DASHBOARD_EMBED_PREVIEW_URL. Clean single-source-of-truth replacing ~8 previously scattered hardcoded strings.
src/services/checkout.ts APP_CHECKOUT_BASE_URL updated from https://worldmonitor.app/ to https://worldmonitor.app/dashboard. buildCheckoutLaunchUrl now generates /dashboard?checkoutProduct=… correctly for the new SPA root.
pro-test/src/services/checkout.ts All three checkout returnUrl/redirectTo sites updated to DASHBOARD_CHECKOUT_SUCCESS_URL from the new routes.ts. Correct for new sessions created after deployment.
src/services/meta-tags.ts Refactored to derive CANONICAL_URL and PUBLIC_ORIGIN separately from variant-meta.ts, cleanly supporting the move of the SPA canonical to /dashboard without regressing OG image URLs.
tests/deploy-config.test.mjs Comprehensive test updates: new assertions for / → welcome.html rewrite, /dashboard → index.html rewrite, /welcome 301 redirect, dashboard canonical, sitemap entries, and the client-side signed-in redirect. Embed rewrite ordering tests updated to disambiguate between the explicit /dashboard rewrite and the catch-all.
index.html Dashboard SPA shell: canonical, OG, Twitter, hreflang, and JSON-LD url fields all updated from https://www.worldmonitor.app/ to https://www.worldmonitor.app/dashboard. CSP gains two new script SHA256 hashes.
src/config/variant-meta.ts url for the full variant changed from https://www.worldmonitor.app/ to https://www.worldmonitor.app/dashboard, driving canonical and OG URL updates throughout meta-tags.ts.
public/sitemap.xml Adds /dashboard (priority 0.8) and removes /welcome. The root / entry (priority 1.0) is retained unchanged.

Sequence Diagram

sequenceDiagram
    participant U as User / Browser
    participant V as Vercel Edge
    participant W as /pro/welcome.html
    participant S as /index.html (SPA)
    participant C as WelcomeApp auth check

    Note over U,S: Anonymous visitor
    U->>V: GET /
    V->>W: rewrite → /pro/welcome.html
    W-->>U: 200 Marketing page

    Note over U,S: Legacy welcome link
    U->>V: GET /welcome
    V-->>U: 301 → /

    Note over U,S: Signed-in visitor arriving at /
    U->>V: GET /
    V->>W: rewrite → /pro/welcome.html
    W-->>U: 200 Marketing page (brief)
    U->>C: mayHaveClerkSession() → true
    C->>C: ensureClerk() → clerk.user truthy
    C-->>U: window.location.replace('/dashboard')
    U->>V: GET /dashboard
    V->>S: rewrite → /index.html
    S-->>U: 200 SPA Dashboard

    Note over U,S: Post-checkout return (new sessions)
    U->>V: "GET /dashboard?wm_checkout=success"
    V->>S: rewrite → /index.html
    S-->>U: 200 SPA + success state shown
Loading

Reviews (1): Last reviewed commit: "feat: serve welcome at root and dashboar..." | Re-trigger Greptile

Comment thread pro-test/src/WelcomeApp.tsx Outdated
Comment on lines +23 to +31
} catch {
// Storage can be unavailable in private contexts; fall through to anonymous.
}
return false;
}

export default function WelcomeApp() {
useEffect(() => {
if (!mayHaveClerkSession()) return;

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 Auth redirect strips query params from the current URL

window.location.replace(DASHBOARD_PATH) unconditionally navigates to /dashboard without preserving any query parameters. Any checkout session that was started before this PR deploys — and returns to the old returnUrl of /?wm_checkout=success — would land on the welcome page, trigger this redirect, and arrive at /dashboard with the wm_checkout parameter gone. The SPA's handleCheckoutReturn logic never fires, so the post-checkout success state never shows. The subscription is still activated server-side, but the user gets no UI confirmation. The same loss applies to ?checkoutProduct=, ?ref=, or ?lang= params embedded in external links pointing at /.

A minimal fix is to forward the current window.location.search to the redirect target:

const target = window.location.search
  ? `${DASHBOARD_PATH}${window.location.search}`
  : DASHBOARD_PATH;
window.location.replace(target);

Comment thread vercel.json Outdated
{ "source": "/.well-known/oauth-protected-resource", "destination": "/api/oauth-protected-resource" },
{ "source": "/embed", "destination": "/embed.html" },
{ "source": "/dashboard", "destination": "/index.html" },
{ "source": "/((?!api|mcp|oauth|assets|blog|docs|embed|embed\\.html|favico|map-styles|data|textures|pro|welcome|sw\\.js|workbox-[a-f0-9]+\\.js|manifest\\.webmanifest|offline\\.html|robots\\.txt|sitemap\\.xml|llms\\.txt|llms-full\\.txt|openapi\\.yaml|\\.well-known|wm-widget-sandbox\\.html|mcp-grant\\.html|mcp-grant).*)", "destination": "/index.html" }

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.

P2 Stale welcome exclusion in SPA catch-all rewrite

|welcome| is still in the negative lookahead of the catch-all rewrite source. Since /welcome is now handled by a redirect rule (which Vercel evaluates before rewrites), the exclusion is dead. It currently causes no routing bug, but it implies that welcome paths receive special rewrite treatment — which is no longer true — and could confuse future contributors or silently affect paths like /welcome-guide if they are ever added.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@koala73
koala73 force-pushed the codex/welcome-home-dashboard-route branch from caa9e23 to 8e6d85d Compare June 16, 2026 12:44
@koala73
koala73 merged commit 4fe66de into main Jun 16, 2026
26 checks passed
@koala73
koala73 deleted the codex/welcome-home-dashboard-route branch June 16, 2026 12:51
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