feat(routing): serve public landing at / and move authed index to /home #174
Reference in New Issue
Block a user
Delete Branch "feat/public-landing-routing-refactor"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Stripe's compliance crawler fetches the apex URL without executing JS and declined live-mode review when
https://resolutionflow.com/returned the empty SPA shell that redirected to/landingclient-side. This PR restructures the router so/serves the public landing page directly, moves the authenticated dashboard index to/home, and adds the crawlability surface Stripe expects (robots.txt, sitemap.xml,og:url).Plan:
docs/plans/2026-05-13-public-landing-routing-refactor.mdWhat changes
Router (
router.tsx)/→ newPublicLandingwrapper (LandingPage for anon;<Navigate to="/home">for authed users so there's no marketing-frame flicker before redirect)./home;/trees,/pilot,/admin/*,/account/*,/welcome/*, etc. keep their URLs./landingkept as a one-release stale-bookmark redirect to/. Deletion captured in the plan's follow-ups.ProtectedRouteunauth redirect flipped/landing→/;state.frompreservation untouched.Reference updates
/home: OAuthCallbackPage (incl. invitee?welcome=teammatequery), WelcomeStep1/2/3 dismiss-rest, AssistantChatPage post-escalate, WelcomeRouter completion/dismiss redirects, VerifyEmailPage's three "Go to dashboard" links./home: TopBar logo, AppLayout mobile nav + drawer logo, CommandPalette Dashboard entry./home: NextStepCardran_session.ctaPath, SetupChecklistran_session.path, SessionHistoryPage empty-state CTA./: TermsPage, PrivacyPage, PoliciesPage, ContactPage, PromotionsPage, PublicTemplatesPage (header + footer). SharedSessionPage'sto="/"left as-is — now correctly lands anon visitors on the public landing.Crawlability
frontend/public/robots.txtallowlisting public pages and disallowing the authed app.frontend/public/sitemap.xmlfor/,/pricing,/contact-sales,/contact,/templates,/terms,/privacy,/policies,/promotions.PageMetagainsog:url(defaults towindow.location.href) and switchestwitter:cardtosummary_large_imagewhen anogImageis passed.Risk + escalation
Necessary but not necessarily sufficient. If Stripe's bot executes zero JS, even a
/-routed LandingPage is invisible (Vite still client-renders the marketing page). The documented next escalation is server-side prerendering of public routes viavite-plugin-ssg(captured in the plan, log the decision in.ai/DECISIONS.mdonce this lands).Test plan
tsc --project tsconfig.app.json --noEmitclean..vite-temproot-owned permission — same env issue documented in prior handoffs)./→ marketing renders immediately (no JS-redirect chain)./→ bounces to/homewithout flicker./home→ redirects to/, then post-login returns to/homeviastate.from./landingstill resolves (redirects to/)./home; invitee path lands at/home?welcome=teammate./home./.curl https://resolutionflow.com/robots.txtreturns the new file;curl https://resolutionflow.com/sitemap.xmlreturns valid XML.Manual follow-ups (not in this PR)
$current_url ends with /now means anonymous marketing visit, no longer authed dashboard. Re-key any insights/funnels..ai/DECISIONS.mdentry capturing SSR-prerender as the documented next escalation./landingredirect alias after one release..ai/HANDOFF.mdto reflect the new resume point.🤖 Generated with Claude Code