Skip to main content

Firebase Hosting Configuration

Master the firebase.json file to unlock the full power of Firebase Hosting.

Basic Structure​

Every Firebase Hosting project needs a firebase.json file:

{
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}

Configuration Options​

Public Directory​

Specify which directory contains your files to deploy:

{
"hosting": {
"public": "dist" // Common for build tools
}
}

Common values:

  • public - Default for static sites
  • dist - Vue, Vite
  • build - Create React App
  • .next - Next.js
  • out - Next.js static export

Ignore Files​

Prevent files from being deployed:

{
"hosting": {
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**",
"**/*.log",
"src/**",
"*.md"
]
}
}

Clean URLs​

Remove .html extensions from URLs:

{
"hosting": {
"cleanUrls": true
}
}

Result:

  • /about.html → /about
  • /contact.html → /contact

Trailing Slashes​

Control URL formatting:

{
"hosting": {
"trailingSlash": false // or true
}
}

Options:

  • false: /about/ → /about
  • true: /about → /about/

Redirects​

Simple Redirects​

{
"hosting": {
"redirects": [
{
"source": "/old-page",
"destination": "/new-page",
"type": 301
}
]
}
}

Pattern Matching​

{
"hosting": {
"redirects": [
{
"source": "/blog/:post*",
"destination": "https://blog.example.com/:post",
"type": 302
},
{
"source": "/users/:id",
"destination": "/profile?id=:id",
"type": 301
}
]
}
}

Regex Redirects​

{
"hosting": {
"redirects": [
{
"regex": "^/products/([^/]+?)(?:/)?$",
"destination": "/items/:1",
"type": 301
}
]
}
}

Rewrites​

Single Page Applications​

{
"hosting": {
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}

API Routes with Cloud Functions​

{
"hosting": {
"rewrites": [
{
"source": "/api/**",
"function": "api"
},
{
"source": "**",
"destination": "/index.html"
}
]
}
}

Cloud Run Integration​

{
"hosting": {
"rewrites": [
{
"source": "/app/**",
"run": {
"serviceId": "my-app",
"region": "us-central1"
}
}
]
}
}

Headers​

Cache Control​

{
"hosting": {
"headers": [
{
"source": "**/*.@(js|css)",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=31536000, immutable"
}
]
},
{
"source": "**/*.@(jpg|jpeg|gif|png|svg|webp)",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=86400, s-maxage=2592000"
}
]
},
{
"source": "index.html",
"headers": [
{
"key": "Cache-Control",
"value": "no-cache, no-store, must-revalidate"
}
]
}
]
}
}

Security Headers​

{
"hosting": {
"headers": [
{
"source": "**",
"headers": [
{
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
},
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "Referrer-Policy",
"value": "strict-origin-when-cross-origin"
},
{
"key": "Permissions-Policy",
"value": "geolocation=(), microphone=(), camera=()"
}
]
}
]
}
}

CORS Headers​

{
"hosting": {
"headers": [
{
"source": "/api/**",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "*"
},
{
"key": "Access-Control-Allow-Methods",
"value": "GET, POST, OPTIONS"
},
{
"key": "Access-Control-Allow-Headers",
"value": "Content-Type"
}
]
}
]
}
}

Multi-Site Configuration​

Multiple Sites in One Project​

{
"hosting": [
{
"target": "app",
"public": "app/dist",
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
{
"target": "blog",
"public": "blog/public",
"cleanUrls": true
},
{
"target": "docs",
"public": "docs/build",
"redirects": [
{
"source": "/v1/**",
"destination": "https://legacy.example.com/:1",
"type": 301
}
]
}
]
}

Deploy to specific sites:

firebase target:apply hosting app my-app
firebase target:apply hosting blog my-blog
firebase target:apply hosting docs my-docs

firebase deploy --only hosting:app
firebase deploy --only hosting:blog
firebase deploy --only hosting:docs

Internationalization (i18n)​

Basic i18n Setup​

{
"hosting": {
"public": "public",
"i18n": {
"root": "/localized-files"
}
}
}

Directory structure:

/public/
/localized-files/
/en/
index.html
about.html
/es/
index.html
about.html
/fr/
index.html
about.html

Country-Based Routing​

{
"hosting": {
"public": "public",
"i18n": {
"root": "/localized-files"
},
"country": {
"US": "/en",
"ES": "/es",
"FR": "/fr",
"DEFAULT": "/en"
}
}
}

Advanced Patterns​

Environment-Specific Configs​

Create multiple config files:

firebase.json (production):

{
"hosting": {
"public": "dist",
"headers": [
{
"source": "**/*.js",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=31536000"
}
]
}
]
}
}

firebase.staging.json:

{
"hosting": {
"public": "dist",
"headers": [
{
"source": "**",
"headers": [
{
"key": "X-Robots-Tag",
"value": "noindex"
}
]
}
]
}
}

Deploy with:

firebase deploy --config firebase.staging.json

Service Worker Configuration​

{
"hosting": {
"public": "dist",
"headers": [
{
"source": "/service-worker.js",
"headers": [
{
"key": "Cache-Control",
"value": "no-cache"
}
]
}
],
"rewrites": [
{
"source": "/service-worker.js",
"destination": "/service-worker.js"
},
{
"source": "**",
"destination": "/index.html"
}
]
}
}

Configuration Best Practices​

1. Version Your Assets​

Use hashed filenames for cache busting:

app.abc123.js  // Can cache forever
app.def456.css // Can cache forever
index.html // Never cache

2. Security First​

Always include security headers:

{
"headers": [
{
"source": "**",
"headers": [
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "X-Content-Type-Options",
"value": "nosniff"
}
]
}
]
}

3. Optimize for Performance​

  • Cache static assets aggressively
  • Use Brotli/gzip compression (automatic)
  • Implement proper cache headers
  • Use CDN-friendly paths

4. Test Configurations​

Always test locally before deploying:

firebase emulators:start
firebase hosting:channel:deploy test-config

Troubleshooting​

Common Issues​

Redirects not working:

  • Check order (redirects process before rewrites)
  • Verify source patterns
  • Test with curl: curl -I https://yoursite.com/old-path

Headers not applying:

  • More specific patterns override general ones
  • Check source glob patterns
  • Verify in browser DevTools

Rewrites failing:

  • Ensure destination exists
  • Check function/service names
  • Verify regions match

Cache issues:

  • Use versioned filenames
  • Set appropriate cache headers
  • Clear CDN cache if needed

Next Steps​

  • Explore example configurations
  • Review the performance optimization tips in the headers section above
  • Implement the security headers shown in this guide
  • Monitor your site's performance in the Firebase Console