Detailed guide contents
Engineering-led guidance. This guide draws on Productionise's standards and practical engineering experience. Examples are generalised to protect confidentiality.
1. What is an environment variable?
An environment variable is a named value supplied outside the main application code. A website might use one name for its public site address, another for an analytics identifier and another for a server credential. The same code can then receive different values in development, preview and production.
This separation makes configuration easier to change and reduces the temptation to paste values throughout the codebase. It can also support safer access controls when a hosting platform supplies a value only to the server process that needs it. But the words “environment variable” describe how a value is provided, not whether it is confidential.
2. What is an `.env` file?
An `.env` file is one common way to provide environment variables during local development. It is usually a plain-text list of names and values. Not every framework, builder or hosting platform uses these files: production services often hold settings in a dashboard or secret store and inject them during a build or server execution.
A real `.env` file can contain credentials, so it generally should not be committed to source control. Projects often include `.env.example` instead. That example documents required names and safe placeholders—such as `EMAIL_SERVICE_KEY=replace-me`—without containing working credentials. Ignoring the file is useful prevention, but it does not protect a value that the application later places in browser code or network requests.
3. Environment variable does not mean secret
Putting a value in an environment variable removes it from an obvious line of source code. That is worthwhile, but it is only one part of the design. The decisive question is where the value goes next.
Server-side code runs in an environment controlled by the business or hosting provider. It can read a private key, make an authorised request and return only the result the visitor is allowed to receive. Browser code runs on the visitor's device. If a build process copies a value into that code, the visitor receives the value too.
A protected dashboard also cannot change this boundary. A hosting provider may store a variable securely and expose it only during the build, but the built output becomes public if the framework inserts that value into client-side JavaScript. Secure storage before the build does not make the resulting browser bundle private.
- Where is the value stored before use?
- Which application component can read it?
- Does that component run on the server or in the browser?
- Is the value ever included in browser code, page content or a client request?
4. What can the browser see?
A visitor's browser must receive the HTML, CSS, JavaScript and other files needed to display and operate the page. Modern browsers also provide developer tools that show loaded source files and the network requests a page makes. A value delivered in those files, request URLs, headers or bodies should therefore be treated as potentially visible.
Minifying code, choosing an obscure variable name or hiding a setting in a builder interface does not create a reliable secrecy boundary. This does not mean every visible identifier is a vulnerability. Public analytics IDs, map tokens or database publishable keys may be designed for client use, often with separate restrictions. Confirm the intended use in the service provider's current documentation.
5. Public versus private configuration
Configuration describes how the application should behave. Some configuration can legitimately be public: the canonical site URL, a deliberately public analytics identifier or a provider's publishable client key. Secrets are values whose disclosure could grant privileged access, reveal protected information, authorise changes or create material cost. Database passwords, service-role credentials, signing secrets and private API tokens are common examples.
Framework prefixes help developers declare the boundary, but they are conventions rather than security controls. Next.js currently inlines variables beginning `NEXT_PUBLIC_` into browser JavaScript at build time. Vite exposes variables using its client prefix—`VITE_` by default—and explicitly warns against putting sensitive information in them. A misleading name does not make a public value private, and an unprefixed value is not safe if code deliberately sends it to the browser.
- Ask the provider whether the credential is publishable, public, client-side, secret or server-side.
- Check what permissions, data and spending the credential can reach.
- Apply provider-supported domain, origin, quota and permission restrictions where appropriate.
- Do not assume that the phrase “API key” alone tells you whether it must be hidden.
6. Where should a private API key go?
A private API key should be available only to trusted server-side code that needs it. Depending on the application, that code might run in a conventional server, an API route, a managed function or an edge function. The hosting platform's protected configuration or suitable secret-management service supplies the key to that server-side component.
The browser then calls your controlled endpoint. Your server checks the request, applies the necessary permissions and limits, then talks to the external service using the private key. It returns only the result the visitor is allowed to receive. The browser never needs the credential itself.
7. What changes when an AI-built website goes to production?
AI-assisted tools let non-specialists connect useful services quickly. That makes the public/private boundary especially important, but the same issue occurs in conventionally developed websites. The right response is to verify the generated architecture, not blame the tool or assume that a successful preview proves production safety.
Development, preview or staging and production may each need different values. Test services and databases should not quietly become live dependencies. Production credentials may need different permissions, approved domains or origins, spending limits, ownership and recovery arrangements. The production host must receive the required settings; a local `.env` file does not automatically travel with a deployment.
Current platform behaviour differs. Lovable's documentation says authenticated API integrations should use Secrets with server-side Edge Functions rather than frontend code. Replit documents encrypted Secrets as environment variables, but its Static Deployments do not support them and production settings may need to be added separately. Vercel separates Development, Preview and Production variables, and changes apply only to new deployments. Check the current documentation for the platform you actually use.
- List development, preview or staging, and production values separately.
- Use separate credentials where the provider and risk make that practical.
- Confirm production domains, origins, callback addresses and provider restrictions.
- Give each credential the smallest permissions needed for its job.
- Record who owns, changes and recovers every production service.
- Verify the deployed output and customer journey, not only the settings screen.
8. What if a secret has already been exposed?
Stay methodical. First remove the credential from client-side use and stop the affected path if continuing it creates unacceptable risk. Use the provider's controls to revoke or rotate the credential as appropriate, then update the authorised server-side consumer. Review available activity, access and billing records, and determine what the credential could reach.
Deleting the current line of code or adding the file to `.gitignore` does not invalidate a credential that somebody may already have copied. Removing it from Git history can reduce continuing exposure but is a separate, disruptive task; revocation or rotation comes first. After containment, move the privileged operation server-side, reduce permissions and limits where possible, and record how future owners can rotate the replacement.
9. What should the business owner actually check?
You don't need to become a developer. But you should be able to get a clear list of the services and configuration your website relies on. The list should describe each name and purpose without recording secret values, and distinguish expected application behaviour from settings verified at the live provider.
- Which external services does the site use?
- Which credentials and configuration values exist?
- Which values are deliberately public, according to the provider?
- Which values must remain private, and where does each one execute?
- Are production credentials separate and least-privileged where appropriate?
- Who can rotate or revoke them, and are old credentials still valid?
- Could another authorised person recover the accounts and documentation?
- Has the production build been checked for unintended values?
10. Environment variables are one part of production readiness
The instruction “use environment variables” is too small to be a production-readiness decision. You need to know what the site depends on, which values are sensitive, where the code executes and how access, deployment, monitoring, recovery and ownership work together.
During production-readiness reviews, we often find that environment variables are being used, but nobody has verified which values are actually public and which must remain private. The practical goal is simple: know what your site depends on, know which values are sensitive, and make sure sensitive operations happen in the right place.
Should I care?
This matters if…
- Your site connects to an API, database, payment service, email provider or AI service.
- A developer or AI builder has told you a credential is safe because it is in an environment variable or `.env` file.
- You are moving from a private preview to a public domain or changing hosting providers.
It may not be urgent if…
- The prototype is offline, uses only invented information and has no live service credentials.
- The site has no external services or sensitive configuration, although you should confirm that assumption before launch.