Self-host dev: serve the SPA shell for /login and /setup - #1232
Merged
Conversation
The Vite dev server resolves an extensionless request like /login to a colliding web-root module (web/login.tsx shadows /login, web/setup.tsx shadows /setup) and serves it as text/javascript, so a browser navigating to those routes (e.g. Better Auth's MCP-OAuth loginPage 302) renders raw JS instead of the app. In the dev API middleware (which runs before Vite's transform middleware), rewrite genuine document navigations to the index so the html fallback serves index.html and the SPA renders the route. Gated on Sec-Fetch-Dest: document / Accept: text/html and no file extension, so modules, assets, and /@Vite internals pass through untouched. Dev-only: the production static server already serves index.html for unknown routes.
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-cloud | bd5b8de | Jun 30 2026, 11:44 PM |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-marketing | bd5b8de | Commit Preview URL Branch Preview URL |
Jun 30 2026, 11:43 PM |
Contributor
Cloudflare previewTorn down — the PR is closed. |
@executor-js/cli
@executor-js/config
@executor-js/execution
@executor-js/sdk
@executor-js/codemode-core
@executor-js/runtime-quickjs
@executor-js/plugin-file-secrets
@executor-js/plugin-graphql
@executor-js/plugin-keychain
@executor-js/plugin-mcp
@executor-js/plugin-onepassword
@executor-js/plugin-openapi
executor
commit: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In the self-host Vite dev server, a browser navigating to
/login(or/setup) gets the rawlogin.tsxmodule source astext/javascript, not the app. Vite treats the extensionless request as a JS request and its resolver maps/logintoweb/login.tsx, which sits in the Vite root and shadows the route.It only bites the MCP OAuth flow, because that is the one path that does a real server-side document navigation to
/login(Better Auth'soidcConfig.loginPage302). Normal in-app sign-in renders the login page client-side and never GETs/login.Fix
In the dev API middleware (which already runs before Vite's transform middleware), rewrite real page navigations to the index so Vite's html fallback serves
index.html; the SPA then readswindow.locationand renders the right route. Gated onSec-Fetch-Dest: document/Accept: text/htmland no file extension, so modules, assets, and/@viteinternals pass through untouched.Dev-only: the production static server already serves
index.htmlfor unknown routes, with login/setup bundled into the SPA.