How to Configure SPA Routing for Netlify, Firebase, Vercel, Render, and GitHub Pages


Single Page Applications (SPAs) are popular for their smooth navigation and seamless user experience. However, deploying them can be tricky β especially when it comes to handling client-side routing.
In this article, you'll learn how to configure your SPA so that it works properly across Netlify, Firebase, Vercel, Render, and GitHub Pages.
π Why Do SPAs Break on Page Refresh?
SPAs use JavaScript to handle routing on the client side. If you refresh or navigate directly to a non-root URL like /dashboard
, the server (or host) tries to find a physical file at /dashboard
, and it returns a 404 Not Found.
To fix this, we must rewrite all incoming routes to index.html
, allowing the client-side router to handle them.
β Configuration for Different Platforms
β‘ Netlify
Netlify uses a netlify.toml
file or a _redirects
file for configuration.
Create netlify.toml
in your project root:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
β
This tells Netlify to serve index.html
for all paths.
π₯ Firebase Hosting
Firebase uses firebase.json
to configure hosting behavior.
Create or update firebase.json
:
{
"hosting": {
"public": "build",
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
Replace "build"
with your actual build output directory.
β² Vercel
Vercel supports rewrites via vercel.json
.
Create vercel.json
in your root:
{
"rewrites": [
{
"source": "/(.*)",
"destination": "/index.html"
}
]
}
This ensures every route is handled by your SPA.
π Render
Render supports Netlify-style redirects using a _redirects
file.
Create a file at public/_redirects
:
/* /index.html 200
β
Place this in the public
directory so it's available after build.
π C panel
β
.htaccess
for SPA Routing (cPanel / Apache Hosting)
Place this in the root of your public folder (typically public_html/
or dist/
):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
π What it does:
RewriteEngine On
: Enables rewrite functionality.RewriteBase /
: Sets the base URL for rewriting.RewriteRule ^index\.html$ - [L]
: Leavesindex.html
untouched.RewriteCond %{REQUEST_FILENAME} !-f
: Only rewrites if the file doesnβt exist.RewriteCond %{REQUEST_FILENAME} !-d
: Only rewrites if the directory doesnβt exist.RewriteRule . /index.html [L]
: Redirects all unknown routes toindex.html
.
π GitHub Pages
GitHub Pages doesnβt support server rewrites. Use one of these workarounds:
Option 1: Use Hash Routing
Use HashRouter
instead of BrowserRouter
(for React apps):
import { HashRouter } from 'react-router-dom';
const App = () => (
<HashRouter>
{/* your routes */}
</HashRouter>
);
Option 2: Add a 404 fallback
Copy index.html
as 404.html
after building:
cp build/index.html build/404.html
GitHub Pages will serve 404.html
when a route is not found, effectively loading your app.
π Example File Structure
my-spa-project/
βββ public/
β βββ _redirects # (for Render)
β βββ netlify.toml # (for Netlify)
β βββ firebase.json # (for Firebase)
β βββ vercel.json # (for Vercel)
βββ README.md
π‘ Pro Tip: Build Before Deploying
Always run your build command before deploying:
npm run build
# or
yarn build
Make sure you're deploying the correct output folder (build
, dist
, etc.)
π§© Conclusion
SPA deployments are simple once you understand the need for route rewriting. Each platform has its quirks, but now you're equipped to handle all of them like a pro.
If you're deploying your SPA to any of these platforms, just follow the steps above and your client-side routing will work seamlesslyβeven on page refresh.
Subscribe to my newsletter
Read articles from Amit Gajare directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Amit Gajare
Amit Gajare
I am beginner to the world of web development and i hope to learn much more and I intend to do my part by sharing interesting topics.