Why Your React App Deployed to GitHub Pages Can't Find Its Way Home
Deploying a React application to GitHub Pages is a common practice for showcasing projects or building simple websites. However, you might encounter a frustrating issue where your app struggles to find its own root URL, especially if you're using a BrowserRouter
from React Router. This usually manifests as errors related to missing routes or components not rendering correctly.
Scenario:
Let's say you have a simple React app with the following structure:
// App.js
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './Home';
import About from './About';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
export default App;
You build this app and deploy it to GitHub Pages using the following configuration in your package.json
:
{
"homepage": "https://your-username.github.io/your-repo-name",
"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
}
}
After deployment, you navigate to https://your-username.github.io/your-repo-name
expecting to see your home page. Instead, you're greeted with a blank page or a message that your routes are not found.
Why is this happening?
The core problem lies in how BrowserRouter
determines the application's root URL. It uses the window.location.pathname
property, which in a typical web server environment would correctly identify the root. However, GitHub Pages serves your application directly from the root (/
) of your GitHub repository. This means window.location.pathname
returns /
, which is not the intended root of your application.
The Solution:
To fix this, we need to explicitly tell BrowserRouter
what the root URL should be. We achieve this by setting the basename
prop:
// App.js
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './Home';
import About from './About';
function App() {
return (
<BrowserRouter basename="/your-repo-name">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
export default App;
By setting basename
to the name of your repository, BrowserRouter
now correctly understands that your application's root is actually /your-repo-name
within the GitHub Pages context.
Additional Considerations:
- HashRouter: If you prefer a different routing approach, consider using
HashRouter
from React Router. It uses the hash portion of the URL (#
) to determine routes, making it less susceptible to issues with GitHub Pages. - GitHub Pages Configuration: Ensure that your
homepage
property inpackage.json
matches the URL you intend to deploy to.
In Summary:
By correctly setting the basename
property on BrowserRouter
, you can overcome the challenges of deploying your React app to GitHub Pages and ensure your routes function as expected. This simple change provides the context necessary for BrowserRouter
to identify the correct root of your application.