People searching “VITE env Laravel” add VITE_OPENAI_API_KEY and then the key is in the built JavaScript. The Vite guide covers the dev server. This page is the prefix.
TL;DR
- Only VITE_ keys reach import.meta.env.
- Vite 4 and later (including 6 and 7) restart the dev server on their own when you save
.env. - Secrets stay unprefixed.
- Do not print
import.meta.envon a production page to debug.
The fix#
A key the browser may see:
VITE_APP_NAME="${APP_NAME}"const name = import.meta.env.VITE_APP_NAME;Anything without the prefix is invisible to Vite. That includes APP_KEY and provider keys. The AI SDK guide keeps those on the server.
Vite reads .env at startup, but since Vite 4 (including Vite 6 and 7) a running npm run dev watches the .env files in envDir and restarts itself when you save one. You will see server restarted in the terminal. If the value still looks old, reload the page. A manual restart is only needed on Vite 3 and older, or when the file sits outside envDir. The Vite guide still says to restart by hand, but the source has done it for you since 4.0.
What to avoid#
Gotcha
Do not print import.meta.env on a production page to debug. It lists every public variable. Do not move a secret into VITE_ for one afternoon and leave it.
FAQ#
How do I expose a Vite variable without exposing a secret?
Only VITE_ keys reach import.meta.env. Vite 4+ restarts the dev server itself when .env changes. Secrets stay unprefixed.
What goes wrong with VITE env Laravel?
Many developers add VITE_OPENAI_API_KEY and then the key is in the built JavaScript. Do not print import.meta.env on a production page to debug.



