Firebase Hosting handles redirects and rewrites through the firebase.json configuration file. Add entries to the redirects array for 301 or 302 status-code redirects, and use the rewrites array to route paths to Cloud Functions or other destinations without changing the URL. Redirects are evaluated before rewrites, and both support glob patterns for flexible path matching.
URL Redirects and Rewrites in Firebase Hosting
When you rename pages, change URL structures, or move content, you need redirects to preserve SEO and prevent broken links. Firebase Hosting supports both redirects (which change the browser URL with a 301 or 302 response) and rewrites (which serve different content without changing the URL). Both are configured declaratively in firebase.json and deployed with the Firebase CLI.
Prerequisites
- A Firebase project with Hosting initialized (firebase init hosting)
- Firebase CLI installed and logged in
- A deployed Firebase Hosting site with existing content
- Basic understanding of HTTP status codes (301, 302)
Step-by-step guide
Add a simple 301 redirect for a renamed page
Add a simple 301 redirect for a renamed page
A 301 redirect tells search engines and browsers that a page has permanently moved. Use this when you rename a URL path and want all traffic (and SEO value) to flow to the new URL. Add an entry to the redirects array in firebase.json with the source path, destination URL, and type 301.
1{2 "hosting": {3 "public": "dist",4 "redirects": [5 {6 "source": "/old-page",7 "destination": "/new-page",8 "type": 3019 },10 {11 "source": "/blog/2023/intro",12 "destination": "/blog/getting-started",13 "type": 30114 }15 ]16 }17}Expected result: Visiting /old-page returns a 301 response with a Location header pointing to /new-page.
Use glob patterns for path-based redirects
Use glob patterns for path-based redirects
Glob patterns let you redirect multiple URLs with a single rule. Use * to match any single path segment and ** to match multiple segments. Capture groups in the source are referenced in the destination with :capture_name syntax. This is useful for restructuring entire URL hierarchies.
1{2 "hosting": {3 "public": "dist",4 "redirects": [5 {6 "source": "/blog/:year/:slug",7 "destination": "/articles/:slug",8 "type": 3019 },10 {11 "source": "/docs/v1/**",12 "destination": "/docs/v2/:0",13 "type": 30114 },15 {16 "source": "/category/:name/posts/:postId",17 "destination": "/posts/:postId",18 "type": 30119 }20 ]21 }22}Expected result: /blog/2024/my-post redirects to /articles/my-post and /docs/v1/auth/setup redirects to /docs/v2/auth/setup.
Redirect to an external domain
Redirect to an external domain
You can redirect Firebase Hosting URLs to external domains. This is useful for migrating sections of your site to a different platform, or for short URL services. The destination can be any absolute URL. External redirects work with both 301 and 302 status codes.
1{2 "hosting": {3 "public": "dist",4 "redirects": [5 {6 "source": "/support",7 "destination": "https://help.example.com",8 "type": 3029 },10 {11 "source": "/github",12 "destination": "https://github.com/your-org/your-repo",13 "type": 30114 },15 {16 "source": "/api/legacy/**",17 "destination": "https://old-api.example.com/:0",18 "type": 30119 }20 ]21 }22}Expected result: Visiting /support on your Firebase Hosting domain redirects the browser to https://help.example.com.
Set up rewrites to route paths to Cloud Functions
Set up rewrites to route paths to Cloud Functions
Rewrites serve content from a different source without changing the browser URL. The most common use case is routing API paths to Cloud Functions. Add entries to the rewrites array with a source glob and a function name. Firebase Hosting proxies the request to the Cloud Function and returns the response.
1{2 "hosting": {3 "public": "dist",4 "rewrites": [5 {6 "source": "/api/**",7 "function": {8 "functionId": "api",9 "region": "us-central1"10 }11 },12 {13 "source": "/webhook",14 "function": "webhookHandler"15 },16 {17 "source": "**",18 "destination": "/index.html"19 }20 ]21 }22}Expected result: Requests to /api/users are handled by the api Cloud Function, while all other paths serve index.html for SPA routing.
Understand the evaluation order of redirects, rewrites, and static files
Understand the evaluation order of redirects, rewrites, and static files
Firebase Hosting evaluates rules in a specific order: (1) reserved URLs like /__/auth, (2) exact static file matches, (3) redirects in order, (4) static files with cleanUrls and trailing slash processing, (5) rewrites in order. This means redirects always run before rewrites, and existing static files are served before any rules apply. Understanding this order is critical when debugging why a rule is not matching.
1// Evaluation order:2// 1. Reserved Firebase URLs (/__/auth, /__/firebase)3// 2. Exact file match in public directory4// 3. Redirects (first match wins, top to bottom)5// 4. cleanUrls / trailingSlash processing6// 5. Rewrites (first match wins, top to bottom)7// 6. Custom 404 page89// Example: If /about.html exists as a static file:10// - A redirect from /about will NOT apply (static file matched first)11// - A rewrite from /about will NOT apply (static file matched first)12// - To force a redirect, rename or delete the static fileExpected result: You understand the evaluation order and can debug rules that are not matching as expected.
Deploy and test your redirect configuration
Deploy and test your redirect configuration
Deploy your updated firebase.json with the Firebase CLI. Then test each redirect by visiting the source URL and verifying the browser redirects to the correct destination. Use curl with the -I flag to inspect response headers, confirming the correct status code (301 or 302) and Location header. Test rewrites by verifying the response content comes from the expected source.
1# Deploy hosting configuration2firebase deploy --only hosting34# Test a redirect (check status code and Location header)5curl -I https://your-project.web.app/old-page6# Expected output:7# HTTP/2 3018# location: /new-page910# Test a rewrite (should return Cloud Function response)11curl https://your-project.web.app/api/health12# Expected output: response from your Cloud Function1314# Test with preview channel first15firebase hosting:channel:deploy test-redirects --expires 1dExpected result: All redirects return the correct status code and destination. Rewrites serve content from the expected Cloud Functions or destinations.
Complete working example
1{2 "hosting": {3 "public": "dist",4 "cleanUrls": true,5 "trailingSlash": false,6 "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],7 "redirects": [8 {9 "source": "/old-page",10 "destination": "/new-page",11 "type": 30112 },13 {14 "source": "/blog/:year/:slug",15 "destination": "/articles/:slug",16 "type": 30117 },18 {19 "source": "/docs/v1/**",20 "destination": "/docs/v2/:0",21 "type": 30122 },23 {24 "source": "/support",25 "destination": "https://help.example.com",26 "type": 30227 },28 {29 "source": "/github",30 "destination": "https://github.com/your-org/your-repo",31 "type": 30132 }33 ],34 "rewrites": [35 {36 "source": "/api/**",37 "function": {38 "functionId": "api",39 "region": "us-central1"40 }41 },42 {43 "source": "/webhook",44 "function": "webhookHandler"45 },46 {47 "source": "**",48 "destination": "/index.html"49 }50 ],51 "headers": [52 {53 "source": "/index.html",54 "headers": [55 { "key": "Cache-Control", "value": "no-cache" }56 ]57 },58 {59 "source": "/assets/**",60 "headers": [61 { "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }62 ]63 }64 ]65 }66}Common mistakes when setting up URL Redirects and Rewrites in Firebase Hosting
Why it's a problem: Placing the catch-all SPA rewrite before specific API rewrites, causing API routes to return index.html instead of the function response
How to avoid: Always place specific rewrites before the catch-all. Firebase evaluates rewrites in order and uses the first match.
Why it's a problem: Using 301 redirects for temporary changes like A/B tests, causing browsers to cache the redirect permanently
How to avoid: Use 302 for temporary redirects. Browsers cache 301 redirects aggressively, making them hard to undo once a user has visited the URL.
Why it's a problem: Forgetting that static files take precedence over redirects and rewrites, so the rule never fires
How to avoid: Check if a file with the same name exists in your public directory. Remove or rename the file, or use a different source path in your redirect.
Best practices
- Use 301 for permanent URL changes to transfer SEO value and 302 for temporary redirects that may be reversed
- Place specific rewrites (API routes) before catch-all rewrites (SPA routing) in the rewrites array
- Use glob captures (:name and **) to create dynamic redirect rules that handle entire URL hierarchies
- Test redirects with curl -I to verify the status code and Location header before and after deploying
- Deploy redirect changes to a preview channel first to avoid breaking production URLs
- Document all redirects in a spreadsheet or comments in firebase.json for future reference
- Review redirects periodically and remove rules for pages that no longer exist at the source URL
- Combine redirects with cleanUrls to avoid duplicate content issues from URLs with and without .html extensions
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I am restructuring my Firebase Hosting site. I need to redirect all /blog/YYYY/slug URLs to /articles/slug with a 301, route /api/** to a Cloud Function named api in us-central1, redirect /support to an external help site, and serve index.html as a catch-all for my SPA. Write the complete firebase.json hosting configuration.
Set up URL redirects in my firebase.json: redirect /old-page to /new-page (301), redirect /blog/:year/:slug to /articles/:slug (301), redirect /support to https://help.example.com (302). Add a rewrite for /api/** to a Cloud Function named api and a catch-all SPA rewrite to index.html.
Frequently asked questions
What is the difference between a redirect and a rewrite in Firebase Hosting?
A redirect sends an HTTP 301 or 302 response that tells the browser to navigate to a different URL — the browser URL changes. A rewrite serves content from a different source (like a Cloud Function) without changing the browser URL.
Are Firebase Hosting redirects evaluated before rewrites?
Yes. The evaluation order is: reserved URLs, static files, redirects, cleanUrls/trailingSlash processing, then rewrites. Redirects always take precedence over rewrites for the same path.
Can I use regex in Firebase Hosting redirect rules?
Firebase Hosting uses glob patterns, not full regex. You can use * for a single path segment, ** for multiple segments, and :name for named captures. For more complex matching, route to a Cloud Function via a rewrite and handle the logic in code.
How do I redirect www to non-www or vice versa?
Firebase Hosting does not support host-based redirects in firebase.json. Set up both www and non-www as custom domains, then use a Cloud Function rewrite or configure the redirect at the DNS level with your domain registrar.
Do redirects affect my Firebase Hosting bandwidth quota?
Redirect responses are very small (just headers, no body) and count minimally against your bandwidth quota. They do not serve files from your public directory.
How many redirects can I have in firebase.json?
There is no documented hard limit on the number of redirect rules. However, keep the list manageable for maintainability. For hundreds of legacy redirects, consider using a Cloud Function rewrite with a lookup table instead.
Can RapidDev help migrate URLs and set up redirects for my Firebase site?
Yes. RapidDev can audit your existing URL structure, create a redirect map for SEO preservation, configure firebase.json with the correct rules, and verify that all redirects work correctly after deployment.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation