mirror of
https://github.com/supabase/supabase.git
synced 2026-09-09 11:30:17 +08:00
**Stack 2/6** of the TanStack Start migration (#46424). Stacked on **#47107** (S1) — review that first; this PR's diff is just the compat shims. > [!NOTE] > Purely additive. Next never imports these files — under TanStack they're wired in via Vite aliases (`next/*` → `@/compat/next/*`). No routes consume them yet (that begins in stack 3). ## What's in this PR `apps/studio/compat/next/*` — drop-in shims so the existing pages-router code runs unchanged under TanStack Start: - `link`, `router`, `navigation`, `head`, `image`, `legacy/image`, `script`, `dynamic`, `server`, `_router-events` — React/runtime shims over `@tanstack/react-router`. - `api.ts` — `toWebHandler`, which adapts a pages-router API handler `(req, res)` into a TanStack server-route Web `fetch` handler. ## Verification On top of S1: `studio` typecheck ✓, lint (0 errors) ✓. Next build is unaffected (nothing imports these under tsc). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added broad Next.js compatibility support for routing, links, dynamic imports, images, scripts, head metadata, navigation hooks, server responses, and API handlers. * Improved handling of redirects, pathname/search params, base paths, and event callbacks for smoother app behavior. * **Tests** * Added coverage for URL resolution and dynamic route interpolation to verify Next-style routing behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
32 lines
1.6 KiB
TypeScript
32 lines
1.6 KiB
TypeScript
import type { ReactNode } from 'react'
|
|
|
|
// Next/Head's job is to inject children into the document `<head>` and
|
|
// deduplicate them by `key` prop. React 19 ships native "document
|
|
// metadata" hoisting: any `<title>`, `<meta>`, `<link>`, `<style>`, or
|
|
// `<script>` rendered anywhere in the tree is hoisted to `<head>`
|
|
// automatically and works for both client render and SSR. Studio uses
|
|
// `<Head>` exclusively for those elements (`<title>`, `<meta>`,
|
|
// `<link>` — see `pages/maintenance.tsx`, `pages/claim-project.tsx`,
|
|
// etc.), so the shim can be a passthrough that lets React do the
|
|
// hoisting.
|
|
//
|
|
// Trade-offs vs the previous `createPortal(children, document.head)`
|
|
// approach:
|
|
// - SSR: the portal returned `null` on the server, so head content
|
|
// from `<Head>` was never in the prerendered HTML. Native hoisting
|
|
// emits the metadata in the prerendered output.
|
|
// - Deduplication: React 19 dedupes `<title>` (last one wins, same
|
|
// as `document.title`) and merges `<meta>`/`<link>` by their
|
|
// attributes. Next dedupes by an explicit `key` prop. The
|
|
// observable output is equivalent for the consumer set we have.
|
|
// - Non-metadata children: React 19 only hoists the metadata tags
|
|
// listed above. If a consumer ever renders an arbitrary element
|
|
// inside `<Head>`, it'll render in place rather than in `<head>`.
|
|
// We have no such consumers today; if one shows up, swap to a
|
|
// portal+SSR-collector setup.
|
|
|
|
// eslint-disable-next-line no-restricted-exports
|
|
export default function Head({ children }: { children?: ReactNode }) {
|
|
return <>{children}</>
|
|
}
|