Mobile/LAN Testing
Mobile/LAN Login Troubleshooting
Use this only for local dashboard testing on a trusted LAN. It does not change production auth settings.
Use this when something is not behaving as expected.
Use this only for local dashboard testing on a trusted LAN. It does not change production auth settings.
Start the dashboard for LAN
Run:
pnpm dev:lanThis serves the web app on 0.0.0.0:3000, which allows another device on the same network to reach the dashboard.
pnpm dev:lan starts the dashboard/web app only. To review the documentation app at http://localhost:3001 at the same time, run this separately in another terminal:
pnpm dev:docsFind the Windows IPv4 address
Run:
ipconfigFind the active Wi-Fi or Ethernet adapter and copy the IPv4 Address, for example 192.168.1.23.
Open from a phone
Connect the phone to the same Wi-Fi network, then open:
http://<PC-IP>:3000Example:
http://192.168.1.23:3000Auth environment
For normal desktop development keep:
BETTER_AUTH_URL=http://localhost:3000In local development, Better Auth resolves the current request host and accepts these port 3000 origins:
http://localhost:3000http://127.0.0.1:3000- private LAN IPs such as
http://192.168.18.22:3000,http://10.x.x.x:3000, andhttp://172.16.x.xthroughhttp://172.31.x.x
If a local hostname outside those patterns is needed, add only that development host to the untracked .env:
BETTER_AUTH_DEV_ALLOWED_HOSTS=my-dev-host.local:3000Restart pnpm dev:lan after changing .env. Do not use a LAN URL for production, do not commit .env, and do not weaken production secure-cookie or trusted-origin behavior.
Sprint 16B LAN sign-out fix record
Root cause:
- LAN sign-out depended on hydrated client-side auth code.
- On local LAN dev origins, Next.js dev resources can be blocked or delayed, so the page can load while the client sign-out handler does not reliably clear the active session.
- Sign-out must clear the cookie for the current request host and redirect relative to that same host, not hardcode
localhost.
Files changed for the fix:
apps/web/src/components/logout-button.tsxapps/web/src/app/logout/submit/route.tsapps/web/src/app/login/page.tsxapps/web/next.config.tsapps/docs/content/mobile-lan-testing.md
Auth/session/cookie/redirect behavior:
- The sign-out button now submits a regular POST form to
/logout/submit. - The server route calls Better Auth sign-out when available.
- If the auth client path is unavailable in local LAN dev, the route deletes the active database session from the current
submicron.session_tokencookie. - The route expires host-only
submicron.session_tokencookies and redirects to/loginon the same request host. - Production secure-cookie behavior remains unchanged.
Retest result to record after local verification:
http://localhost:3000/loginlogin and sign-out work.http://192.168.18.22:3000/loginlogin and sign-out work on the computer.http://192.168.18.22:3000/loginlogin and sign-out work on the phone.
Remaining limitation:
- LAN testing still requires the phone and PC to be on the same trusted local network, and a dev server running with
pnpm dev:lan.
Sprint 15 LAN login fix record
Root cause:
- Better Auth originally trusted only the configured
BETTER_AUTH_URL, so local LAN origins such ashttp://192.168.18.22:3000could fail origin/callback validation even though the page loaded. - The login form was client-handled only. During local LAN/loopback testing, if the client submit handler was not active yet, the browser could fall back to native form submission and return to the login page without a useful visible error.
- When the app is served on
0.0.0.0, server-side redirects must be rebuilt from the incomingHostheader so they return tolocalhost,127.0.0.1, or the LAN IP instead of0.0.0.0.
Files changed for the fix:
apps/web/src/lib/auth.tsapps/web/src/lib/auth-diagnostics.tsapps/web/src/app/api/auth/[...all]/route.tsapps/web/src/app/api/dev/auth-diagnostics/route.tsapps/web/src/app/login/page.tsxapps/web/src/app/login/submit/route.tsapps/web/src/components/login-form.tsxapps/web/src/proxy.ts.env.exampleapps/docs/content/mobile-lan-testing.mdapps/docs/content/local-development.md
Auth, session, cookie, and redirect changes:
- Local development auth resolves the current request host for
localhost:3000,127.0.0.1:3000, and private LAN IPs on port3000. - Production auth remains static and secure; secure-cookie behavior is not weakened for production.
- Development cookies remain host-only,
sameSite=lax, path/, and non-secure only for local HTTP development. - The login form posts to
/login/submitas a progressive-enhancement fallback while the hydrated client still uses Better Auth directly. /login/submitforwards the form credentials to Better Auth, copies the session cookie on success, and redirects back to the same incoming host.- Failed login returns to
/login?error=invalid&email=...; the email is preserved and the password is never placed in the URL. - Development-only diagnostics are available at
/api/dev/auth-diagnostics; production returns 404 and no secrets are exposed.
Retest result:
http://localhost:3000/login: verified on the computer. Successful login sets a session cookie, redirects to/, and loads the dashboard.http://127.0.0.1:3000/login: verified on the computer. Successful login sets a session cookie, redirects to/, and loads the dashboard.http://192.168.18.22:3000/login: verified on the computer. Successful login sets a session cookie, redirects to/, and loads the dashboard.http://192.168.18.22:3000/loginon a phone: fixed and verified by user confirmation on the same Wi-Fi network. The phone login reaches the dashboard using the LAN IP host, host-only development cookie, and same-origin redirect path.
Remaining limitations:
- If the phone login regresses later, clear cookies/site data for the LAN IP, restart
pnpm dev:lan, and confirm the phone is on the same Wi-Fi network. - Root
pnpm lintandpnpm testcurrently run the repository typecheck pipeline. Usepnpm typecheckwhen you want the same verification path explicitly.
Troubleshooting
- If login fails on the computer when using
http://<PC-IP>:3000/login, restartpnpm dev:lan, confirm the route is on the current branch, then tryhttp://localhost:3000/login,http://127.0.0.1:3000/login, andhttp://<PC-IP>:3000/login. - Open
http://<PC-IP>:3000/api/dev/auth-diagnosticsduring local development to confirm the request host, host classification, database availability, session-cookie presence, and cookie settings. This route returns 404 in production and does not expose secrets. - If the login form reports a local auth URL error, confirm the browser URL uses port
3000and a localhost, loopback, or private LAN host. - If the form reports that the session could not be created, confirm Docker/PostgreSQL is running and rerun
pnpm db:seedif the admin account may be missing. - If the page loads but login still loops back, clear cookies for the LAN IP and retry after restarting
pnpm dev:lan. - If the phone cannot load the page, confirm the phone and PC are on the same network and Windows Firewall allows local Node.js traffic.
- If a newly added route returns 404 during local dev, restart
pnpm devorpnpm dev:lanand confirm the current Git branch contains the route.
Developer Details
- Source
- apps/docs/content/mobile-lan-testing.md
- Owner
- Module Owner
- Status
- Current
- Module
- Mobile/LAN Testing
- Related route
- None