Password protection
Optional HTTP Basic Auth on Vercel deployments
You can lock a deployed textbook behind HTTP Basic Auth. Static builds are unchanged: opening index.html in a browser (or copying dist/) never asks for a password.
This uses Vercel Routing Middleware on the normal plan. It is not Vercel Advanced Deployment Protection.
Do not put the password in src/book/bookConfig.json. That file is committed, imported by the React app, and values end up in the JS bundle.
Enable on Vercel
- In the textbook's Vercel project, add an environment variable:
PASSWORD, orTBX_ACCESS_PASSWORD(used ifPASSWORDis unset)
- Redeploy so middleware picks up the value.
If the variable is unset or empty, the hosted book stays public.
Do not prefix the variable with VITE_. That would embed the secret in client JavaScript.
What to tell the client
The browser shows a native username and password dialog. Only the password is checked; the username can be anything.
Example: username book, password <the secret>.
What is protected
Every request to the Vercel URL, including HTML, JS, CSS, and page images. Direct *.vercel.app and custom-domain URLs are gated the same way.
middleware.ts sits at the book root. New books from tbx create include it. Existing books pick it up with tbx update, then set the env var and redeploy.
Local development
The same Basic Auth check runs in vite dev and vite preview when PASSWORD or TBX_ACCESS_PASSWORD is set (for example in .env.local). Leave it unset while authoring so you are not prompted on every reload.
vite build does not read the password and does not inject a gate into the output.
What is not protected
npm run buildoutput (dist/releaseand theONE_FILEdist/release_inlinebundle)- Opening
index.htmlfrom disk or any static host that is not Vercel - Local
vite dev/vite previewwhen the env var is unset
Changing the password
Update the env var on Vercel and redeploy. Middleware reads the value at deploy time.