Firebase Hosting is the static-and-edge layer of Google’s Firebase platform. It serves files from a global CDN, gives you free SSL, and plugs into the rest of Firebase — Auth, Firestore, Cloud Functions. It is not a Next.js host in the Vercel sense, and treating it like one is where most beginners get burned. Below is the right mental model, the baseline firebase.json, and the commands to go from zero to live.
Background
Firebase Hosting launched in 2016 and has gradually grown from “static files only” to “static + dynamic rewrites to Cloud Functions / Cloud Run”. In 2026 it sits in an awkward middle: more capable than pure object storage, less capable than a framework-native platform. The right mental model is “a CDN that knows how to call your backend”, not “a Next.js runtime”.
How to tell
- You already use Firebase Auth, Firestore, or Cloud Functions and want one bill.
- Your site is static HTML / a SPA / an Astro static build — not a heavy SSR app.
- You want free SSL and a global CDN without configuring anything.
- You need preview channels for sharing branches with clients.
- You do not need server-side rendering at the edge of every request.
Quick verdict
Use Firebase Hosting when the rest of your stack is already Firebase, or when your site is mostly static. Skip it when you want zero-config Next.js SSR — Vercel is built for that.
Before you start
- A Firebase project (create via console or
firebase projects:create). - Node and
firebase-toolsinstalled (npm install -g firebase-tools). - Static build output ready (
dist/,out/,build/).
Step by step
-
Confirm the output is static. A directory with
index.html, asset folders, and per-route subdirectories. If your output is a Node server (Next.js SSR without static export), reconsider Firebase Hosting. -
Install and authenticate the CLI:
npm install -g firebase-tools
firebase login
firebase projects:list
- Initialize hosting in the project:
firebase init hosting
# ? Public directory? dist
# ? Configure as a single-page app? No (static sites/Astro: No)
# ? Set up automatic builds and deploys with GitHub? (optional)
- Baseline
firebase.jsonfor a static content site:
{
"hosting": {
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"cleanUrls": true,
"trailingSlash": true,
"headers": [
{
"source": "/_astro/**",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
},
{
"source": "**/*.html",
"headers": [
{ "key": "Cache-Control", "value": "no-cache, max-age=0" }
]
},
{
"source": "**/*.@(jpg|jpeg|png|webp|avif|svg|woff2)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=2592000" }
]
}
]
}
}
- Decide on rewrites:
{
"hosting": {
"rewrites": [
{ "source": "/api/**", "function": "api" },
{ "source": "/render/**", "run": { "serviceId": "ssr-render", "region": "us-central1" } }
]
}
}
For SPAs that need an index.html fallback only, use the ** → /index.html rewrite — but never for content sites, where it breaks real 404s.
- Build and deploy:
npm run build
firebase deploy --only hosting
# Hosting URL: https://your-project.web.app
- Test in incognito + curl:
curl -sI https://your-project.web.app/ | grep -i cache-control
curl -sI https://your-project.web.app/this-does-not-exist/ | head -1
# expect HTTP/2 404 (not 200)
- Add a custom domain. Firebase Console → Hosting → Add custom domain → follow DNS prompts (typically two A records to Firebase’s anycast IPs and a CNAME for www). SSL is automatic.
Implementation checklist
publicmatches the framework’s output directory.- Cache headers explicit for HTML vs hashed assets.
- No accidental
**rewrite to/index.htmlon a content site. - Custom domain green check + SSL valid.
- Deploy releases tracked (Hosting → Release history).
After-launch verification
curl -sIshows expected cache headers.- A deliberate 404 returns HTTP 404, not 200.
- The
*.web.appURL and custom domain both serve identical content. - Preview channel via
firebase hosting:channel:deployproduces a shareable URL.
Common pitfalls
- Treating Firebase Hosting as a Next.js host — SSR support exists via Cloud Functions but is not as smooth as Vercel.
- Forgetting to set
cleanUrls/ trailing slash behavior, then chasing 404s after deploy. - Leaving the default cache (1 hour) on HTML pages and wondering why updates do not show up.
- Deploying the wrong
publicdirectory — usually the source folder instead of the build output. - Adding a SPA catch-all rewrite by accident — every URL returns the homepage.
FAQ
- Is Firebase Hosting free?: There is a generous Spark (free) tier with 10 GB storage and 360 MB/day transfer. Plenty for most indie sites.
- Does Firebase Hosting do SSR?: Indirectly, by rewriting requests to a Cloud Function or Cloud Run. It is not a first-class runtime like Vercel.
- Can I use Firebase Hosting without other Firebase services?: Yes. You can host a plain static site with no Auth, Firestore, or Functions. Most people who do this eventually wish they had picked something framework-native instead.
- Do I get HTTPS automatically?: Yes. Both the default
*.web.appURL and custom domains get free SSL through Let’s Encrypt. - How do I roll back a bad deploy?: Firebase Hosting keeps release history.
firebase hosting:cloneor use the console’s Rollback button.