Skip to content

landing-static: prerender landing page via route groups#47

Merged
x0ba merged 1 commit into
stagingfrom
landing-static/route-groups
May 28, 2026
Merged

landing-static: prerender landing page via route groups#47
x0ba merged 1 commit into
stagingfrom
landing-static/route-groups

Conversation

@x0ba
Copy link
Copy Markdown
Owner

@x0ba x0ba commented May 28, 2026

Why?

The landing page at / was SSR'd on every request because the root layout server load reads auth from cookies. Marketing content is fully static, so we can prerender it as HTML at build time for faster loads and CDN caching on Vercel.

What

  • Split routes into (marketing) and (app) groups (URLs unchanged)
  • Move readUserId, AppShell, and PostHog identify into (app)/+layout.* only
  • Slim root layout to shared CSS/favicon
  • Add export const prerender = true on the landing page
  • Mark dashboard links with rel="external" so the prerender crawler skips auth-protected /runs

Test plan

  • bun run build succeeds and emits prerendered index.html
  • / loads marketing content without hitting serverless auth
  • /runs and /regression still require auth and render with AppShell
  • /sign-in and /sign-up still redirect authenticated users

Split routes into (marketing) and (app) groups so auth only runs on
dashboard routes, and prerender / as static HTML at build time.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 28, 2026

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

Project Deployment Actions Updated (UTC)
flightlog Ready Ready Preview, Comment May 28, 2026 6:30pm

@x0ba x0ba changed the title Prerender landing page via SvelteKit route groups. landing-static: prerender landing page via route groups May 28, 2026
@x0ba x0ba marked this pull request as ready for review May 28, 2026 18:28
Copy link
Copy Markdown
Owner Author

x0ba commented May 28, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 28, 2026

Greptile Summary

This PR restructures the SvelteKit route tree into (app) and (marketing) route groups, allowing the landing page to be prerendered as static HTML at build time. The root layout is stripped down to CSS/favicon only; AppShell and PostHog identify are moved into the new (app) group layout.

  • (marketing)/+page.ts exports prerender = true and all outbound dashboard links are marked rel="external" to stop the prerender crawler from following auth-protected routes.
  • (app)/+layout.server.ts (renamed from the root) continues to provide userId to all authenticated routes, and (app)/+layout.svelte wraps them unconditionally with AppShell.
  • Sign-in and sign-up pages stay in (marketing) and keep their own +page.server.ts auth-redirect checks — they are not affected by the prerender setting on the landing page.

Confidence Score: 5/5

Safe to merge — the refactor is a clean mechanical split with no logic changes to auth or app routes.

Every app route is a pure rename into (app) with no content changes. The sign-in/sign-up pages keep their own server-side auth redirects and are unaffected by the landing page's prerender flag. The root layout losing its server data dependency is exactly what's needed to allow prerendering, and rel="external" correctly stops the crawler at dashboard links. No auth logic was altered.

No files require special attention.

Important Files Changed

Filename Overview
src/routes/(marketing)/+page.ts Adds export const prerender = true — the entire motivation of the PR. Single-line change, correct and sufficient.
src/routes/(app)/+layout.server.ts Renamed from root layout; content is unchanged. Auth read now scoped to (app) group only, enabling prerender of marketing routes.
src/routes/(app)/+layout.svelte New layout for app group; contains AppShell and PostHog identify logic moved from the root layout. Unconditional AppShell render is correct since all (app) routes are authenticated.
src/routes/+layout.svelte Stripped to CSS import, favicon, and {@render children()}. Removing server data dependency from this file is the key enabler for prerendering.
src/routes/(marketing)/+page.svelte Three dashboard links gain rel="external" to prevent the prerender crawler from following them to auth-protected routes. No other functional changes.
src/routes/(marketing)/sign-in/+page.server.ts Renamed only; still calls readUserId(event) directly so the auth-redirect still works without needing a parent layout server.
src/routes/(marketing)/sign-up/+page.server.ts Same as sign-in: renamed only, auth redirect logic intact.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Root["+layout.svelte\nCSS + favicon only"]

    Root --> Marketing["(marketing) group\nno layout server"]
    Root --> App["(app) group\n+layout.server.ts → userId"]

    Marketing --> Landing["/ +page.svelte\nprerender = true ✓"]
    Marketing --> SignIn["/sign-in +page.server.ts\nreadUserId → redirect if authed"]
    Marketing --> SignUp["/sign-up +page.server.ts\nreadUserId → redirect if authed"]

    App --> AppLayout["(app)/+layout.svelte\nAppShell + PostHog identify"]
    AppLayout --> Runs["/runs"]
    AppLayout --> RunId["/runs/[id]"]
    AppLayout --> Regression["/regression"]
    AppLayout --> RegressionId["/regression/[id]"]
    AppLayout --> RegressionRuns["/regression/runs/[id]"]

    Landing -->|"rel=external links\n(crawler stops here)"| Runs
Loading

Reviews (1): Last reviewed commit: "Prerender landing page via SvelteKit rou..." | Re-trigger Greptile

@x0ba x0ba merged commit e0cfff0 into staging May 28, 2026
4 of 5 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.

1 participant