To configure environment variables in Lovable, open the Cloud tab (click the + button next to Preview) and go to the Secrets section. Add your API keys and tokens there — they are encrypted and automatically injected into Edge Functions. For frontend variables, use the VITE_ prefix so Vite embeds them at build time. When deploying to Vercel or Netlify, copy VITE_SUPABASE_URL, VITE_SUPABASE_PUBLISHABLE_KEY, and VITE_SUPABASE_PROJECT_ID into the hosting platform's environment variable settings.
Why environment variables and secrets need careful setup in Lovable
Environment variables store sensitive data like API keys, database URLs, and third-party tokens outside of your source code. In Lovable, these are managed through the Secrets panel inside the Cloud tab — not through .env files you edit by hand. The most common mistake is hardcoding API keys directly into your React components or utility files. This is dangerous because Lovable projects can be public by default on the Free plan, meaning anyone viewing your project code can see those keys. Even on paid plans, keys in source code get committed to GitHub when you connect your repository. Another frequent issue is the VITE_ prefix requirement. Lovable uses Vite as its build tool, and Vite only exposes environment variables that start with VITE_ to your frontend code. If you name a variable SUPABASE_URL instead of VITE_SUPABASE_URL, your React components cannot access it. Meanwhile, Edge Functions receive all secrets automatically without any prefix requirement. When you deploy outside of Lovable (to Vercel, Netlify, or another host), the Secrets you configured in Lovable do not transfer automatically. You must manually set each environment variable on the hosting platform, using the exact same names and values.
- API keys hardcoded in source code instead of stored in Secrets
- Missing VITE_ prefix on variables that need to be accessible in frontend code
- Secrets not copied to external hosting platform (Vercel, Netlify) during deployment
- Referencing process.env instead of import.meta.env in Vite-based projects
- Build-time vs runtime confusion — VITE_ variables are baked in during build, not read at runtime
- Auto-added Supabase secrets deleted or overwritten accidentally
Error messages you might see
Uncaught ReferenceError: process is not definedYou are using process.env.VARIABLE_NAME in your code, but Lovable uses Vite which uses import.meta.env instead. Replace process.env with import.meta.env everywhere in your frontend code.
TypeError: Cannot read properties of undefined (reading 'VITE_SUPABASE_URL')The environment variable VITE_SUPABASE_URL is not set. Either you have not added it to Cloud tab → Secrets, or (if deploying externally) you have not set it on your hosting platform.
Invalid API KeyThe Supabase API key in your environment variables is wrong, expired, or missing. Check Cloud tab → Secrets for the correct VITE_SUPABASE_PUBLISHABLE_KEY value.
supabaseUrl is requiredThe Supabase client is being initialized without a URL. This means import.meta.env.VITE_SUPABASE_URL is undefined — the variable is either not set or missing the VITE_ prefix.
Before you start
- A Lovable project open in the editor
- The API keys or tokens you need to configure (from Stripe, OpenAI, or other services)
- If deploying externally: access to your Vercel or Netlify project dashboard
- If using Supabase: your project URL and anon key from the Supabase dashboard
How to fix it
Add secrets in the Cloud tab Secrets panel
Secrets in the Cloud tab are encrypted and injected into Edge Functions automatically
Add secrets in the Cloud tab Secrets panel
Secrets in the Cloud tab are encrypted and injected into Edge Functions automatically
Open your Lovable project. Click the + button next to the Preview panel to open additional panels. Select Cloud tab from the options. In the Cloud tab, scroll down or click Secrets in the sidebar. You will see any auto-added secrets (like Supabase keys) already listed. Click Add Secret, enter the variable name (for example STRIPE_SECRET_KEY) and paste the value. Click Save. The secret is now encrypted and available to your Edge Functions immediately. Never enter API keys directly in your code — always use this Secrets panel.
// WRONG: API key hardcoded in source codeconst stripe = new Stripe('sk_live_abc123realkey');// CORRECT: Key stored in Secrets, accessed via Edge Function// In your Edge Function (supabase/functions/create-payment/index.ts):const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!);Expected result: Your secret appears in the Secrets list with its value hidden. Edge Functions can access it via Deno.env.get().
Use the VITE_ prefix for frontend-accessible variables
Vite only exposes variables with the VITE_ prefix to your browser-side React code
Use the VITE_ prefix for frontend-accessible variables
Vite only exposes variables with the VITE_ prefix to your browser-side React code
For any environment variable your React components need to read directly (like the Supabase URL or a public API key), the variable name must start with VITE_. This is a Vite security feature — it prevents accidental exposure of server-side secrets to the browser. In your code, access these variables using import.meta.env.VITE_VARIABLE_NAME. Private keys (like Stripe secret keys) should NOT have the VITE_ prefix and should only be accessed from Edge Functions.
// WRONG: Missing VITE_ prefix — this will be undefined in the browserconst supabaseUrl = import.meta.env.SUPABASE_URL;// CORRECT: VITE_ prefix makes it available to frontend codeconst supabaseUrl = import.meta.env.VITE_SUPABASE_URL;const supabaseKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY;Expected result: Your frontend code can read the variable values. Console.log confirms the values are defined (not undefined).
Create a centralized environment config file
A single config file prevents typos and makes it easy to see all required variables at a glance
Create a centralized environment config file
A single config file prevents typos and makes it easy to see all required variables at a glance
Create a file at src/config/env.ts that exports all your environment variables with proper type checking and fallback handling. This way, every component imports from one place, and you get clear errors if a variable is missing. This pattern also makes it obvious which variables your project depends on — helpful when setting up external deployments.
// WRONG: Scattered import.meta.env calls across many files// src/components/Dashboard.tsxconst url = import.meta.env.VITE_SUPABASE_URL;// src/lib/api.tsconst url = import.meta.env.VITE_SUPABASE_URL; // duplicated// src/config/env.ts — single source of truthexport const ENV = { supabaseUrl: import.meta.env.VITE_SUPABASE_URL ?? '', supabaseKey: import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY ?? '', supabaseProjectId: import.meta.env.VITE_SUPABASE_PROJECT_ID ?? '',} as const;// Warn in development if any required variable is missingif (!ENV.supabaseUrl || !ENV.supabaseKey) { console.warn('Missing required environment variables. Check Cloud tab → Secrets.');}Expected result: All components import from src/config/env.ts. Missing variables trigger a clear warning in the console.
Copy environment variables to Vercel or Netlify for external deployment
Lovable Secrets do not automatically transfer to external hosting platforms
Copy environment variables to Vercel or Netlify for external deployment
Lovable Secrets do not automatically transfer to external hosting platforms
When deploying your Lovable project to Vercel or Netlify via GitHub, you must manually set every VITE_ environment variable on the hosting platform. In Vercel: go to your project dashboard, click Settings, then Environment Variables. Add each variable with the exact same name and value as in Lovable. At minimum, you need VITE_SUPABASE_URL, VITE_SUPABASE_PUBLISHABLE_KEY, and VITE_SUPABASE_PROJECT_ID if your project uses Supabase. After adding the variables, trigger a redeployment so the build picks up the new values. If this involves coordinating environment variables across multiple services (Supabase, Stripe, OAuth providers), RapidDev's engineers have configured these exact deployment pipelines across 600+ Lovable projects and can ensure nothing is missed.
Expected result: Your externally deployed app functions identically to the Lovable preview, with all API connections working.
Verify variables are loaded correctly in your running app
A quick verification prevents hours of debugging wrong or missing values
Verify variables are loaded correctly in your running app
A quick verification prevents hours of debugging wrong or missing values
After configuring secrets, verify they are actually available in your app. Add a temporary console.log in your main App.tsx or a component that uses the variable. Check the browser console in the Preview panel. For Edge Functions, check the Logs section in the Cloud tab after triggering the function. Once verified, remove the console.log — never log secret values in production code. If a variable shows as undefined, double-check the exact name (including VITE_ prefix) in Cloud tab → Secrets.
// Variable might be undefined but you don't knowconst client = createClient(import.meta.env.VITE_SUPABASE_URL, import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY);// Temporary check — remove after verifyingconsole.log('Supabase URL defined:', !!import.meta.env.VITE_SUPABASE_URL);console.log('Supabase Key defined:', !!import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY);// Never log the actual values — only log whether they existconst client = createClient(import.meta.env.VITE_SUPABASE_URL, import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY);Expected result: Console shows 'true' for both variables. If either shows 'false', the variable is not configured correctly.
Complete code example
1/**2 * Centralized environment variable configuration.3 * All components should import from this file4 * instead of accessing import.meta.env directly.5 *6 * VITE_ prefix = available in browser (public).7 * Non-VITE_ secrets = only available in Edge Functions.8 */910export const ENV = {11 // Supabase connection (auto-added by Lovable Cloud)12 supabaseUrl: import.meta.env.VITE_SUPABASE_URL ?? '',13 supabaseAnonKey: import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY ?? '',14 supabaseProjectId: import.meta.env.VITE_SUPABASE_PROJECT_ID ?? '',1516 // App configuration17 appUrl: import.meta.env.VITE_APP_URL ?? window.location.origin,18 isProduction: import.meta.env.PROD,19 isDevelopment: import.meta.env.DEV,20} as const;2122// Type-safe environment variable access23export type EnvConfig = typeof ENV;2425// Validation: warn if required variables are missing26const requiredVars = [27 ['VITE_SUPABASE_URL', ENV.supabaseUrl],28 ['VITE_SUPABASE_PUBLISHABLE_KEY', ENV.supabaseAnonKey],29] as const;3031for (const [name, value] of requiredVars) {32 if (!value) {33 console.warn(34 `Missing environment variable: ${name}. ` +35 'Add it in Cloud tab → Secrets (Lovable) or ' +36 'in your hosting platform environment settings.'37 );38 }39}Best practices to prevent this
- Never hardcode API keys in source code — always store them in Cloud tab → Secrets, where they are encrypted
- Use the VITE_ prefix only for variables that the browser needs to read; keep private keys prefix-free and access them only from Edge Functions
- Create a centralized env.ts config file so every component imports variables from one place
- Add validation that warns when required variables are missing — this surfaces configuration problems immediately
- When deploying to Vercel or Netlify, copy every VITE_ variable manually — Lovable Secrets do not auto-export
- Use import.meta.env (not process.env) in all frontend code — Lovable projects use Vite, not webpack
- Keep a .env.example file in your repo listing all required variable names (without values) as documentation for your team
- After changing secrets, trigger a new build — VITE_ variables are embedded at build time, not read at runtime
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I have a Lovable (lovable.dev) project using Vite + React + TypeScript + Supabase. I need help configuring environment variables. Here is my current setup: - Supabase client initialization: [paste your supabase.ts or client.ts file] - Any other API configurations: [paste relevant config files] - Deployment target: [Lovable hosting / Vercel / Netlify] Please: 1. Identify any hardcoded API keys or secrets that should be moved to environment variables 2. Show me the correct import.meta.env syntax for each variable 3. Create a centralized env.ts config file with type checking 4. List which variables need the VITE_ prefix and which should only be in Edge Functions 5. Tell me exactly which variables I need to set on my deployment platform
Review my project for any hardcoded API keys or secrets in the source code. Move all sensitive values to environment variables accessed via import.meta.env with the VITE_ prefix for frontend variables. Create a centralized config file at src/config/env.ts that exports all environment variables with validation warnings for missing values. Make sure the Supabase client uses import.meta.env.VITE_SUPABASE_URL and import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY. Do not hardcode any actual key values in the code.
Frequently asked questions
Where are environment variables configured in Lovable?
Open your project, click the + button next to the Preview panel, select Cloud tab, then click Secrets. This is where you add, edit, and manage all environment variables. Secrets are encrypted and automatically injected into Edge Functions.
What is the VITE_ prefix and why do I need it?
Lovable uses Vite as its build tool. Vite only exposes environment variables with the VITE_ prefix to your frontend (browser) code. Variables without this prefix are only available in server-side contexts like Edge Functions. This is a security feature that prevents accidental exposure of private keys.
Do Lovable secrets automatically transfer to Vercel or Netlify?
No. When you deploy your Lovable project to Vercel, Netlify, or any other hosting platform, you must manually set every environment variable on that platform. Go to your hosting project settings, find the environment variables section, and add each VITE_ variable with the same name and value.
Why does my app show 'process is not defined' error?
Lovable projects use Vite, which uses import.meta.env instead of process.env (which is a Node.js/webpack convention). Replace every instance of process.env.VARIABLE_NAME with import.meta.env.VARIABLE_NAME in your frontend code. Make sure the variable has the VITE_ prefix.
How do I access secrets inside a Supabase Edge Function?
Edge Functions automatically receive all secrets configured in Cloud tab → Secrets. Access them using Deno.env.get('SECRET_NAME'). You do not need the VITE_ prefix for Edge Function secrets — in fact, private keys should not have the VITE_ prefix to prevent browser exposure.
Can I use a .env file in Lovable?
Lovable generates a .env file automatically when you connect Supabase, and you can view it in Dev Mode. However, the recommended approach is to use Cloud tab → Secrets for managing variables. The .env file is useful for reference (seeing variable names and values) but Secrets is the primary configuration method.
Why are my environment variables undefined after deployment?
VITE_ variables are embedded at build time, not read at runtime. If you added or changed a variable after the last build, you need to trigger a new build for the changes to take effect. On external platforms like Vercel, add the variables in project settings and then redeploy.
What if I cannot get my environment variables working myself?
Environment variable configuration across Lovable, Supabase, and external hosting platforms involves coordinating multiple services. RapidDev's engineers have set up these exact configurations across 600+ Lovable projects and can ensure your secrets, API keys, and deployment variables are all correctly wired.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your issue.
Book a free consultation