-
Create
.envfile (copy from.env.example):cp .env.example .env
-
Edit
.envand add your Firebase credentials:VITE_FIREBASE_API_KEY=AIza...your_actual_key VITE_FIREBASE_AUTH_DOMAIN=my-project.firebaseapp.com # ... rest of config
-
Load via localStorage (browser console):
// Paste this in browser console to test locally: const env = { VITE_FIREBASE_API_KEY: "AIza...", VITE_FIREBASE_AUTH_DOMAIN: "my-project.firebaseapp.com", VITE_FIREBASE_PROJECT_ID: "my-project", VITE_FIREBASE_STORAGE_BUCKET: "my-project.firebasestorage.app", VITE_FIREBASE_MESSAGING_SENDER_ID: "123456789", VITE_FIREBASE_APP_ID: "1:123456789:web:abc123", VITE_FIREBASE_MEASUREMENT_ID: "G-XXXXX" }; Object.entries(env).forEach(([k, v]) => localStorage.setItem(k, v)); location.reload();
-
Install Vite:
npm install --save-dev vite npm install --save-dev @vitejs/plugin-basic-ssl
-
Create
vite.config.js:import { defineConfig } from 'vite' export default defineConfig({ server: { https: false } })
-
Update
package.json:{ "scripts": { "dev": "vite", "build": "vite build" } } -
Run development server:
npm run dev
-
Build for production:
npm run build # Vite will read .env and inject variables # Upload dist/ folder to your host
Environment Variables Setup:
- Dashboard → Site Settings → Build & Deploy → Environment
- Add variables:
VITE_FIREBASE_API_KEYVITE_FIREBASE_AUTH_DOMAINVITE_FIREBASE_PROJECT_IDVITE_FIREBASE_STORAGE_BUCKETVITE_FIREBASE_MESSAGING_SENDER_IDVITE_FIREBASE_APP_IDVITE_FIREBASE_MEASUREMENT_ID
Build command: npm run build or vite build
Publish directory: dist
Environment Variables Setup:
- Project Settings → Environment Variables
- Add each variable with Production/Preview scopes
- Redeploy to apply
Example vercel.json:
{
"buildCommand": "npm run build",
"outputDirectory": "dist"
}Create .github/workflows/deploy.yml:
name: Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build with env vars
env:
VITE_FIREBASE_API_KEY: ${{ secrets.VITE_FIREBASE_API_KEY }}
VITE_FIREBASE_AUTH_DOMAIN: ${{ secrets.VITE_FIREBASE_AUTH_DOMAIN }}
VITE_FIREBASE_PROJECT_ID: ${{ secrets.VITE_FIREBASE_PROJECT_ID }}
VITE_FIREBASE_STORAGE_BUCKET: ${{ secrets.VITE_FIREBASE_STORAGE_BUCKET }}
VITE_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.VITE_FIREBASE_MESSAGING_SENDER_ID }}
VITE_FIREBASE_APP_ID: ${{ secrets.VITE_FIREBASE_APP_ID }}
VITE_FIREBASE_MEASUREMENT_ID: ${{ secrets.VITE_FIREBASE_MEASUREMENT_ID }}
run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./distAdd secrets to GitHub:
- Repository → Settings → Secrets and variables → Actions
- Click "New repository secret"
- Add each
VITE_*variable
- Go to Firebase Console
- Click your project (or create one)
- Click ⚙️ → Project Settings
- Go to "Your apps" section
- Click the
</>icon for your web app - Copy all the values from the config object
Example from Firebase:
const firebaseConfig = {
apiKey: "AIzaSyAbgO_Q6euLImJMjb1O2vu-gNUreD57eoQ", // ← Copy this
authDomain: "bcs-planner.firebaseapp.com", // ← Copy this
projectId: "bcs-planner", // ← Copy this
// ... etc
};Paste each value into your .env file.
- NEVER commit
.envfile to Git (it's in.gitignore) - NEVER hardcode secrets in the code
- NEVER expose secrets in client-side comments
- DO use different API keys for development and production (optional but recommended)
- DO restrict Firebase API key usage in Firebase Console
- Go to APIs & Services → Credentials
- Restrict key to only your domain
- Restrict to specific APIs (Firestore, etc.)
Q: "Firebase API Key not found" warning
- A: Make sure
.envfile exists and is filled in, OR your deployment platform has environment variables set
Q: Firestore connection fails in production
- A: Check that API key is correct and Firebase Security Rules allow read/write
Q: "Cannot read property 'firebase' of undefined"
- A: config.js needs to load before any Firebase initialization. Check
index.htmlload order.
Need help? Check the main README.md