Playwright navigated to the local dev server. The root / returned a 404 — but oddly, the AppShell was still rendering around it. A prior session had added basePath: '/app' to next.config.ts, and a public/index.html placeholder was supposed to redirect to /app.
The bug: with basePath set, Next.js serves public/ files under the basePath prefix in dev mode. So public/index.html was landing at /app/index.html — not at /. The placeholder was silently useless.
The fix: Next.js middleware runs entirely outside the basePath context. A middleware redirecting / → /app when NODE_ENV !== 'production' solves it cleanly. In production, the middleware is a no-op — Vercel's CDN serves the marketing site at / directly.
// development/frontend/src/middleware.ts
export function middleware(request: NextRequest) {
if (
process.env.NODE_ENV !== "production" &&
request.nextUrl.pathname === "/"
) {
return NextResponse.redirect(new URL("/app", request.url));
}
}
export const config = { matcher: ["/"] };