@@ -11,24 +11,49 @@ import { createRouter } from '@tanstack/react-router';
1111import { routeTree } from './routeTree.gen' ;
1212
1313/**
14- * Compute the router basepath from Vite's `BASE_URL` .
14+ * Compute the router basepath for TanStack Router .
1515 *
16- * When Studio is mounted under a sub-path (e.g. `/_studio/` via the CLI `--ui`
17- * flag, which sets `VITE_BASE=/_studio/`), TanStack Router must strip that
18- * prefix before matching route patterns. Otherwise URLs such as
19- * `/_studio/packages` are mis-interpreted as `/$package="_studio"/packages`.
16+ * When Studio is mounted under a sub-path (e.g. `/_studio/`), TanStack Router
17+ * must strip that prefix before matching route patterns. Otherwise URLs such
18+ * as `/_studio/packages` are mis-interpreted as `/$package="_studio"/packages`.
2019 *
21- * Vite exposes the configured base as `import.meta.env.BASE_URL`:
22- * - Root deployment: `'/'` → basepath `'/'` (no-op)
23- * - Sub-path deployment: `'/_studio/'` → basepath `'/_studio'`
20+ * Resolution order (first match wins):
21+ *
22+ * 1. **Runtime global `window.__OBJECTSTACK_STUDIO_BASEPATH__`** — injected
23+ * into `index.html` by the host server (see `createStudioStaticPlugin`
24+ * in `@objectstack/cli`) when the pre-built dist is served under a
25+ * sub-path. This is the authoritative signal for *any* deployment where
26+ * the same pre-built bundle is re-hosted at a different mount point —
27+ * `import.meta.env.BASE_URL` is a build-time constant and cannot
28+ * capture this.
29+ *
30+ * 2. **Vite `import.meta.env.BASE_URL`** — works at dev-server time when
31+ * `VITE_BASE` is set (e.g. the CLI dev proxy), and for bundles that
32+ * were explicitly built with a non-default `base` config.
33+ *
34+ * 3. Fallback: `'/'` (root deployment).
2435 *
2536 * TanStack Router expects the basepath WITHOUT a trailing slash (except for
2637 * the root `'/'`), so we normalise accordingly.
2738 */
39+ function normalise ( base : string ) : string {
40+ const trimmed = base . trim ( ) ;
41+ if ( ! trimmed || trimmed === '/' || trimmed === './' ) return '/' ;
42+ return trimmed . endsWith ( '/' ) ? trimmed . slice ( 0 , - 1 ) : trimmed ;
43+ }
44+
2845function resolveBasepath ( ) : string {
29- const base = ( import . meta. env . BASE_URL ?? '/' ) . trim ( ) ;
30- if ( ! base || base === '/' || base === './' ) return '/' ;
31- return base . endsWith ( '/' ) ? base . slice ( 0 , - 1 ) : base ;
46+ // 1. Runtime injection from host server (works for any pre-built dist)
47+ if ( typeof window !== 'undefined' ) {
48+ const injected = ( window as unknown as { __OBJECTSTACK_STUDIO_BASEPATH__ ?: string } )
49+ . __OBJECTSTACK_STUDIO_BASEPATH__ ;
50+ if ( typeof injected === 'string' && injected . length > 0 ) {
51+ return normalise ( injected ) ;
52+ }
53+ }
54+
55+ // 2. Vite build-time / dev-server base
56+ return normalise ( import . meta. env . BASE_URL ?? '/' ) ;
3257}
3358
3459export const router = createRouter ( {
0 commit comments