Skip to content

Feat/landing ssr tanstack start - #1333

Open
Sharqiewicz wants to merge 8 commits into
stagingfrom
feat/landing-ssr-tanstack-start
Open

Feat/landing ssr tanstack start#1333
Sharqiewicz wants to merge 8 commits into
stagingfrom
feat/landing-ssr-tanstack-start

Conversation

@Sharqiewicz

@Sharqiewicz Sharqiewicz commented Aug 13, 2026

Copy link
Copy Markdown
Member

Prerender the marketing pages to static HTML

Migrates the frontend from a client-rendered SPA to TanStack Start, so the
marketing pages are rendered to static HTML at build time instead of booting
an empty shell. Crawlers and first-paint now get real content.

What changed

  • 21 pages prerendered — 7 marketing routes × 3 locale variants
    (unprefixed, /en, /pt-BR) — served by Netlify as plain files.
  • /widget opts out (ssr: false) and renders from a prerendered SPA
    shell. The ramp flow depends on wallet SDKs and persisted machine state that
    only exist in the browser.
  • Server-safety fixes so app code survives a DOM-less render:
    localStorage probed with typeof, server snapshots for
    useSyncExternalStore, createAppKit moved behind a window guard, Globe
    sized from CSS instead of a measured viewport.
  • src/tests/ssr-safety.test.tsx pins each of those regressions.

Netlify configuration

Two files under apps/frontend/: netlify.toml (build command, publish dir) and
_redirects (all routing rules, copied into dist/client by the build).

The publish directory moved from dist to dist/client. Note that netlify.toml
overrides the Netlify UI settings once deployed, and the build runs
--frozen-lockfile, so bun.lock must be committed and in sync.

Netlify serves real files before applying non-forced rules, which is what lets the
/* /404.html 404 catch-all coexist with the prerendered pages.

Adding a marketing page: add the route under src/routes/{-$locale}/ and add its
path to MARKETING_ROUTES in vite.config.ts. Miss the second step and it works in dev
but 404s in production, with no build error.

Adding a locale: add the prefix to LOCALE_PREFIXES in vite.config.ts.

Adding a client-only route: set ssr: false on the route and add a _redirects
rewrite to /_shell.html for each locale variant. Don't add it to MARKETING_ROUTES
the shell is appended last and would overwrite the real page.

@netlify

netlify Bot commented Aug 13, 2026

Copy link
Copy Markdown

Deploy Preview for vortexfi ready!

Name Link
🔨 Latest commit c9f72b6
🔍 Latest deploy log https://app.netlify.com/projects/vortexfi/deploys/6a7f1ddf08c0b00008e5dc49
😎 Deploy Preview https://deploy-preview-1333--vortexfi.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Aug 13, 2026

Copy link
Copy Markdown

Deploy Preview for vortex-sandbox failed. Why did it fail? →

Name Link
🔨 Latest commit c9f72b6
🔍 Latest deploy log https://app.netlify.com/projects/vortex-sandbox/deploys/6a7f1ddf2c44b8000951b514

@netlify

netlify Bot commented Aug 13, 2026

Copy link
Copy Markdown

Deploy Preview for vrtx-dashboard failed. Why did it fail? →

Name Link
🔨 Latest commit c9f72b6
🔍 Latest deploy log https://app.netlify.com/projects/vrtx-dashboard/deploys/6a7f1ddf362ff70008123dd1

@ebma
ebma requested a balanced review from Copilot August 13, 2026 16:13

Copilot AI left a comment

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.

Pull request overview

Migrates the frontend to TanStack Start, prerendering localized marketing pages while retaining the widget as a client-only flow.

Changes:

  • Adds static prerendering for 21 localized marketing routes.
  • Introduces TanStack Start hydration, routing, and Netlify deployment configuration.
  • Adds DOM-less rendering safeguards and SSR regression tests.

Reviewed changes

Copilot reviewed 25 out of 26 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
bun.lock Updates TanStack Start and Vite dependencies.
apps/frontend/vite.config.ts Configures prerendering and SPA shell generation.
apps/frontend/src/wagmiConfig.ts Guards AppKit initialization from SSR.
apps/frontend/src/tests/ssr-safety.test.tsx Adds DOM-less rendering tests.
apps/frontend/src/services/storage/local.ts Makes storage access server-safe.
apps/frontend/src/routeTree.gen.ts Regenerates frontend route metadata.
apps/frontend/src/routes/{-$locale}/widget.tsx Disables SSR for the widget.
apps/frontend/src/routes/__root.tsx Adds the Start document and providers.
apps/frontend/src/router.tsx Creates per-render router and query clients.
apps/frontend/src/main.tsx Removes the former SPA entry point.
apps/frontend/src/i18n.ts Extracts SSR-compatible localization initialization.
apps/frontend/src/hooks/useSyncFormToUrl.ts Uses the server-safe token hook.
apps/frontend/src/hooks/useRampUrlParams.ts Uses the server-safe token hook.
apps/frontend/src/hooks/useEvmTokensLoaded.ts Adds an external-store server snapshot.
apps/frontend/src/contexts/rampState.tsx Avoids persisted-state reads during SSR.
apps/frontend/src/components/ToastPopover/index.tsx Adds a toast server snapshot.
apps/frontend/src/components/Ramp/Onramp/index.tsx Adopts the shared token-loading hook.
apps/frontend/src/components/Ramp/Offramp/index.tsx Adopts the shared token-loading hook.
apps/frontend/src/components/Globe/index.tsx Moves responsive sizing to CSS.
apps/frontend/src/client.tsx Adds the TanStack Start hydration entry.
apps/frontend/package.json Adds Start dependencies and updates build paths.
apps/frontend/netlify.toml Publishes the generated client directory.
apps/frontend/index.html Removes the former Vite HTML shell.
apps/frontend/CLAUDE.md Documents SSR architecture and conventions.
apps/frontend/_redirects Routes widget URLs to the SPA shell.
apps/dashboard/src/routeTree.gen.ts Regenerates dashboard route ordering.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

<PersistentRampStateProvider>
<PolkadotNodeProvider>
<PolkadotWalletStateProvider>
<NetworkProvider>
Comment thread apps/frontend/src/client.tsx Outdated
// Initialize dynamic EVM tokens from SquidRouter API (falls back to static config on failure)
initializeEvmTokens();

hydrateStart().then(router => {
Comment on lines +51 to +52
if (typeof window !== "undefined") {
createAppKit({
Comment thread apps/frontend/CLAUDE.md Outdated
- **Routing**: TanStack Router — route tree auto-generated in `src/routeTree.gen.ts` (do not hand-edit).
- **Rendering**: TanStack Start. Marketing routes are prerendered to static HTML at build time
(`dist/client`); `/widget` sets `ssr: false` and is served from the `_shell.html` SPA shell.
See [`docs/adr-0004-landing-page-ssr.md`](../../docs/adr-0004-landing-page-ssr.md).
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