From eb826e9ed0135e639e0c6bc316595a2d7bb63a2d Mon Sep 17 00:00:00 2001 From: Jordan Ellery Date: Fri, 2 Oct 2026 16:30:22 +1000 Subject: [PATCH] feat: serve the app under a base path Set BASE_PATH to serve the app, its routes and the mock API under a path, such as behind a proxy. Unset, everything stays at the root. Co-Authored-By: Claude Opus 5.5 --- src/lib/api-client.ts | 2 +- src/main.tsx | 2 +- vite-plugin-mock-api.ts | 6 +++++- vite.config.ts | 2 ++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/lib/api-client.ts b/src/lib/api-client.ts index 4707e2d..efe19fd 100644 --- a/src/lib/api-client.ts +++ b/src/lib/api-client.ts @@ -1,4 +1,4 @@ -const API_ROOT = '/api' +const API_ROOT = `${import.meta.env.BASE_URL}api` class ApiError extends Error { readonly status: number diff --git a/src/main.tsx b/src/main.tsx index d664ee9..fbd02cd 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -9,7 +9,7 @@ const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, refetchOnWindowFocus: false } }, }) -const router = createRouter({ routeTree }) +const router = createRouter({ routeTree, basepath: import.meta.env.BASE_URL }) declare module '@tanstack/react-router' { interface Register { diff --git a/vite-plugin-mock-api.ts b/vite-plugin-mock-api.ts index 0a388bd..865c065 100644 --- a/vite-plugin-mock-api.ts +++ b/vite-plugin-mock-api.ts @@ -34,8 +34,12 @@ const mockApiPlugin = (): Plugin => { const module = await server.ssrLoadModule(HANDLERS_MODULE) const middleware = createMiddleware(...(module.handlers as RequestHandler[])) + // This runs ahead of vite's own middleware, so requests still carry the base. + const apiRoot = `${server.config.base}api/` server.middlewares.use((request, response, next) => { - if (!request.url?.startsWith('/api/')) return next() + if (!request.url?.startsWith(apiRoot)) return next() + // The handlers are written against the root, as the test suite serves them. + request.url = request.url.slice(server.config.base.length - 1) addExpressAccessors(request as unknown as ExpressLikeRequest) return middleware(request, response, next) }) diff --git a/vite.config.ts b/vite.config.ts index e4e129d..0e6350f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -6,6 +6,8 @@ import { fileURLToPath } from 'node:url' import { mockApiPlugin } from './vite-plugin-mock-api.ts' export default defineConfig({ + // Lets the app be served under a path, such as behind a proxy. + base: process.env.BASE_PATH ?? '/', plugins: [ tanstackRouter({ target: 'react',