mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 20:05:06 +03:00
feat(studio): serve SPA shell on unprefixed paths too
Keep the base-path-prefixed rewrites for assets and routes that Vite already baked the prefix into, but also emit root-level rewrites so bare-domain hits (including /) resolve to the shell instead of Vercel's default 404.
This commit is contained in:
1 parent
47f11bcd49
commit
9ee354ee65
2 files changed
+26
-24
No files matched your search
@@ -1,6 +1,5 @@
|
||||
// api/server.ts
|
||||
// @ts-ignore - built at `vite build` time, not present in source
|
||||
import handler from '../dist/server/server.js'
|
||||
|
||||
// eslint-disable-next-line import/no-anonymous-default-export, no-restricted-exports
|
||||
export default (request: Request) => handler.fetch(request)
|
||||
export default (request) => handler.fetch(request)
|
||||
+25
-22
@@ -11,28 +11,31 @@ export const config: VercelConfig = {
|
||||
outputDirectory: 'dist/client',
|
||||
cleanUrls: true,
|
||||
rewrites: [
|
||||
// API + server-function passthrough. Both funnel through the single
|
||||
// `/api/server` Vercel Function that TanStack Start generates. These
|
||||
// must come before the asset rule so that extensioned API paths like
|
||||
// `/api/foo.json` still hit the function instead of a filesystem lookup.
|
||||
// The destination is un-prefixed because the function is registered at
|
||||
// `/api/server` regardless of the app's base path.
|
||||
routes.rewrite(`${basePath}/api/(.*)`, '/api/server'),
|
||||
routes.rewrite(`${basePath}/_serverFn/(.*)`, '/api/server'),
|
||||
// Asset passthrough. Matches anything ending in `.ext` (e.g.
|
||||
// `/foo/assets/bundle.abc.js`) and rewrites to the un-prefixed path so
|
||||
// Vercel finds it in `dist/client/`. If the file doesn't exist Vercel
|
||||
// 404s — important, otherwise missing JS would fall through to the
|
||||
// shell rule below and the browser would get HTML where JS was
|
||||
// expected.
|
||||
routes.rewrite(`${basePath}/(.*\\.\\w+)`, '/$1'),
|
||||
// SPA fallback. Every remaining path (including the base path itself)
|
||||
// gets served the prerendered shell, which boots the client router. The
|
||||
// destination is `/_shell` (no extension) because `cleanUrls: true`
|
||||
// makes Vercel key static assets by their clean URL — `_shell.html`
|
||||
// lives at `/_shell` in the asset map, so `/_shell.html` wouldn't
|
||||
// resolve.
|
||||
routes.rewrite(`${basePath}/(.*)`, '/_shell'),
|
||||
// Prefixed rules — only emitted when a base path is configured. Vite
|
||||
// bakes `${basePath}/assets/*` URLs into the HTML, so anything hitting
|
||||
// a prefixed path needs to be stripped back to its filesystem location
|
||||
// (or routed to the /api/server function).
|
||||
...(basePath
|
||||
? [
|
||||
routes.rewrite(`${basePath}/api/(.*)`, '/api/server'),
|
||||
routes.rewrite(`${basePath}/_serverFn/(.*)`, '/api/server'),
|
||||
routes.rewrite(`${basePath}/(.*\\.\\w+)`, '/$1'),
|
||||
routes.rewrite(`${basePath}/(.*)`, '/_shell'),
|
||||
]
|
||||
: []),
|
||||
// Root-level rules — always emitted. These serve the app at `/` and
|
||||
// also cover any paths that don't carry the base-path prefix (handy for
|
||||
// health checks, bare-domain hits, or links that forget the prefix).
|
||||
//
|
||||
// Order matters: API + server-function passthrough first so extensioned
|
||||
// API paths (`/api/foo.json`) don't get caught by the asset rule. Asset
|
||||
// rule next — it's an identity rewrite that also guards missing files
|
||||
// from falling through to the shell (a missing `.js` should 404, not
|
||||
// serve HTML). Shell rule last, catching everything else.
|
||||
routes.rewrite('/api/(.*)', '/api/server'),
|
||||
routes.rewrite('/_serverFn/(.*)', '/api/server'),
|
||||
routes.rewrite('/(.*\\.\\w+)', '/$1'),
|
||||
routes.rewrite('/(.*)', '/_shell'),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user