Learn how to configure and deploy your Vite + React app with separate Firebase Hosting environments for staging and production.
Deploying a React + Vite application to Firebase Hosting is super fast. But how do you deploy both a staging and production version to two separate hosting URLs?
In this guide, you'll learn how to:
✅ Configure environment-specific .env
files
✅ Create two Firebase Hosting sites (staging & production)
✅ Use vite
build modes and deploy via simple npm scripts
✅ Avoid common 404 errors with Firebase Hosting
Let’s get started.
🧱 Project Setup
If you’re using Vite and Firebase, your package.json
probably looks something like this:
{
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"firebase": "^11.6.1",
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
}
You also have a firebaseConfig.js
with the Firebase initialization.
🌍 Step 1: Add .env
Files for Staging & Production
Create two environment files in your project root:
.env.staging
VITE_FIREBASE_API_KEY=your-staging-api-key
VITE_FIREBASE_AUTH_DOMAIN=staging-yourproject.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-staging-id
VITE_FIREBASE_STORAGE_BUCKET=...
VITE_FIREBASE_MESSAGING_SENDER_ID=...
VITE_FIREBASE_APP_ID=...
VITE_FIREBASE_MEASUREMENT_ID=...
.env.production
VITE_FIREBASE_API_KEY=your-prod-api-key
VITE_FIREBASE_AUTH_DOMAIN=yourproject.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-prod-id
VITE_FIREBASE_STORAGE_BUCKET=...
VITE_FIREBASE_MESSAGING_SENDER_ID=...
VITE_FIREBASE_APP_ID=...
VITE_FIREBASE_MEASUREMENT_ID=...
In your firebaseConfig.js
, use:
const firebaseConfig = {
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID,
measurementId: import.meta.env.VITE_FIREBASE_MEASUREMENT_ID,
};
🔥 Step 2: Create Hosting Sites on Firebase
We’ll now set up two hosting URLs:
-
https://yourproject.web.app
→ Production -
https://staging-yourproject.web.app
→ Staging
✨ Create staging site:
- Go to Firebase Console
- Open your project
- Go to Hosting
- Click the dropdown arrow next to the current site
- Click Add another site
- Use site ID:
staging-yourproject
🏷️ Step 3: Apply Hosting Targets
In your terminal:
firebase target:apply hosting production yourproject
firebase target:apply hosting staging staging-yourproject
⚙️ Step 4: Update firebase.json
Update your firebase.json
to support both targets:
{
"hosting": [
{
"target": "production",
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [{ "source": "**", "destination": "/index.html" }]
},
{
"target": "staging",
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [{ "source": "**", "destination": "/index.html" }]
}
]
}
🔧 Step 5: Update package.json
Scripts
Add build and deploy commands for each environment:
"scripts": {
"dev": "vite",
"dev:staging": "vite --mode staging",
"dev:production": "vite --mode production",
"build:staging": "vite build --mode staging",
"build:production": "vite build --mode production",
"deploy:staging": "npm run build:staging && firebase deploy --only hosting:staging",
"deploy:production": "npm run build:production && firebase deploy --only hosting:production"
}
🚀 Step 6: Deploy It!
Deploy to staging:
npm run deploy:staging
Deploy to production:
npm run deploy:production
💠 Troubleshooting
🔴 404: Requested entity was not found
You likely tried to deploy to a Firebase Hosting site that doesn’t exist.
✅ Fix: Create it via Firebase Console → Hosting → Add Site.
🔴 auth/invalid-api-key
Your
.env
isn’t being loaded properly.
✅ Fix: Check the VITE_
prefix and make sure you’re building with the correct mode:
vite build --mode staging
🧠 Final Thoughts
Using Firebase Hosting Targets with Vite modes gives you a clean, scalable way to manage multiple environments — with separate hosting URLs and .env
configurations.
This setup works great for teams, CI/CD workflows, and A/B testing deployments.
Happy shipping! 🚀
💬 Questions or feedback? Leave a comment or reach out on Twitter!
Top comments (0)