Variables de entorno en Bolt: qué va en cada lugar
Qué valores de una app de Bolt.new pueden ir en el navegador, cuáles van en Secrets, cómo funcionan VITE_ y otros prefijos y cómo revisar que nada se filtró.
Read in English →
Una app de Bolt.new maneja dos tipos de configuración. Lo público que necesita el navegador, como la URL de Supabase, la clave publishable o anon de Supabase y la clave publicable de Stripe, va en el archivo .env del proyecto con el prefijo público del framework (VITE_ en la mayoría de los proyectos de Bolt). Los secretos, como la clave secreta de Stripe, una clave de OpenAI o la clave secreta de Supabase, van en Secrets dentro de Bolt y solo los leen las funciones de servidor. Todo lo que lleva prefijo público termina en el JavaScript que descarga cada visitante.
A continuación tienes una tabla con los valores más comunes y su lugar, cómo funcionan los prefijos, dónde se configuran en Bolt y en otros servicios, y cómo revisar tu app publicada en busca de claves filtradas.
¿Dónde va cada valor?
| Valor | ¿Puede estar en el navegador? | Dónde va |
|---|---|---|
| URL del proyecto de Supabase | Sí | .env, como VITE_SUPABASE_URL o similar |
Clave publishable de Supabase (sb_publishable_...) o la anon antigua | Sí, con RLS en todas las tablas | .env |
Clave secreta de Supabase (sb_secret_...) o la service_role antigua | No, se salta RLS | Secrets, solo en funciones de servidor |
Clave publicable de Stripe (pk_test_..., pk_live_...) | Sí | .env |
Clave secreta de Stripe (sk_...) y secreto de firma de webhooks (whsec_...) | No | Secrets |
| Claves de OpenAI, Anthropic, Resend y otras APIs | No | Secrets |
| Clave de Google Maps para navegador | Sí, si está restringida a tus dominios | .env |
| Banderas de funciones, nombre de la app, URLs públicas | Sí | .env |
La regla detrás de la tabla: si conocer el valor le permite a alguien gastar tu dinero, leer datos de otras personas o hacerse pasar por tu app, es un secreto.
¿Cómo funcionan VITE_, NEXT_PUBLIC_ y EXPO_PUBLIC_?
El prefijo es lo que usa el framework para decidir qué copia dentro del paquete del navegador. La documentación de Vite indica que solo las variables que empiezan con VITE_ llegan al código del cliente, mediante import.meta.env. Next.js hace lo mismo con NEXT_PUBLIC_ y Expo con EXPO_PUBLIC_.
O sea, el prefijo es una etiqueta que dice "esto es público". El error típico es justo al revés de lo que uno espera: renombrar un secreto a VITE_OPENAI_API_KEY para que el frontend "lo vea". Funciona, y desde ese momento la clave está en un archivo que cualquiera abre con las herramientas de desarrollo del navegador. Las llamadas que necesitan un secreto tienen que pasar por una función de servidor.
¿Dónde se configuran en Bolt?
Los valores públicos
Abre la vista de código y busca un archivo .env en la raíz. Edítalo ahí o pídele a Bolt que lo cree. Si no sabes qué variables espera la app, la ayuda de Bolt sugiere preguntar: List every environment variable the application requires and where each value can be found.
Los secretos
Haz clic en el icono de base de datos arriba del proyecto y luego en Secrets. Escribe un Name que coincida con el que lee la función (por ejemplo OPENAI_API_KEY) y el Value, y guarda. Según la documentación de secretos de Bolt:
- Bolt suele pedirte el secreto después de escribir código que lo necesita, y muestra un aviso
Missing secretscon los que el código usa pero todavía no existen. - Un secreto nuevo queda disponible para las funciones de servidor al instante, sin volver a desplegar.
- Solo el dueño del proyecto, los co-owners y los administradores del equipo pueden verlos o editarlos.
- Si tu base es un proyecto de Supabase que conectaste o reclamaste, los mismos secretos aparecen en el panel de Supabase en Edge Functions > Secrets.
Dentro de una función de servidor, que corre sobre las Edge Functions de Supabase (basadas en Deno), un secreto se lee así:
const apiKey = Deno.env.get('OPENAI_API_KEY');
if (!apiKey) {
return new Response('Server is missing OPENAI_API_KEY', { status: 500 });
}
En otro hosting
Si Netlify, Vercel u otro servicio compila tu app desde GitHub, no ve el .env de Bolt. Agrega ahí las variables públicas y recompila, porque los valores VITE_ quedan fijos al compilar. Los secretos de las funciones de servidor se quedan en Bolt o Supabase; el hosting nunca los necesita. Qué pasa cuando faltan lo contamos en error al publicar Bolt en Netlify.
¿Cómo separo los valores de prueba y de producción?
Usa valores distintos para pruebas y para producción, no solo apps distintas. En Stripe, las claves de prueba empiezan con pk_test_ y sk_test_, las reales con pk_live_ y sk_live_, y cada modo tiene su propio secreto de firma de webhooks. Un clásico del día del lanzamiento: cambiar la clave publicable a la real mientras la función de servidor sigue con la clave secreta de prueba. En variables de entorno de producción y preview mostramos una forma simple de ordenar ambas.
¿Cómo reviso que no se filtró ningún secreto?
Busca en los archivos compilados. Ejecuta
npm run builden la terminal de Bolt y busca prefijos delatores en la carpeta de salida:grep -rE "sk_live|sk_test|sb_secret|service_role|whsec_" dist/Lo ideal es que no aparezca nada.
- Busca en el sitio publicado. Abre tu app y las herramientas de desarrollo del navegador. En el panel Sources, busca en todos los archivos esos mismos prefijos y los nombres de tus proveedores de API.
- Revisa GitHub. Confirma que
.envestá en.gitignorey que ningún commit anterior tiene claves reales. Una clave que alguna vez se subió hay que tratarla como pública. - Corre la auditoría de seguridad de Bolt. En los planes de pago, Run security audit en el menú Publish revisa que las claves privadas no estén en el código ni se envíen al navegador, y no gasta tokens.
Si encuentras un secreto donde no debe estar, moverlo no alcanza. Rótalo en el panel del proveedor (crea una clave nueva, actualiza Secrets y borra la vieja), porque alguien ya pudo copiarla. En clave de API expuesta en el frontend explicamos esa limpieza paso a paso.
Respuestas rápidas
¿La clave anon de Supabase es secreta? No. Está pensada para ser pública y lo que protege los datos es Row Level Security. La que nunca debe llegar al navegador es la service_role o la secreta.
¿Por qué mi variable sale undefined? O le falta el prefijo VITE_, o la agregaste después del último build, o no reiniciaste el servidor de desarrollo tras editar el .env.
¿Puedo poner secretos en el .env si el repositorio es privado? No para nada que lea el frontend. El repositorio privado protege el código fuente, pero el JavaScript compilado sigue siendo público en tu sitio.
¿Tengo que volver a desplegar después de cambiar un secreto en Bolt? Para las funciones de servidor no, según la documentación de Bolt. Los cambios en valores VITE_ sí necesitan un build nuevo.
¿No sabes qué está exponiendo tu app?
La revisión gratuita mira tu app publicada desde afuera, que es justo donde aparecen las claves filtradas. Para una revisión completa de claves, políticas y funciones de servidor, mira nuestra revisión de seguridad de Supabase y el servicio para arreglar apps de Bolt, o escríbenos.


