getting 404 for links with create-react-app deployed to github pages
I'm trying to deploy a create-react-app to a relative path on GitHub pages with a custom domain. E.g. www.example.com/myproject
I'm using react-router-dom
, react-router-redux
and react-router-bootstrap
I've set homepage to http://www.example.com/myproject
in packages.json
(tried homepage = "."
too) and also configured basename for my history:
...
export const history = createHistory({ basename: '/myproject' });
const middleware = [thunk, routerMiddleware(history)];
...
const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers);
const store = createStore(rootReducer, initialState, composedEnhancers);
The deployed app works on www.mydomain.com/myproject
and I can navigate via the app links.
But I got 404 when I try to enter a path directly (eg. www.example.com/myproject/account
) or if I do browser refresh on a subpage.
Long term goal is to configure different relative paths for dev and prod environments as described in this answer but first I just need to make it work in deployment.
Solution 1:
Problem: URL gets evaluated on server side
When you enter a new URL into address bar of the browser or refreshes the page, browser requests server (in this case GitHub pages server) for that URL. At this point, client side router (react-router) can't take action as it is not yet loaded for that page. Now server looks for a route that matches /accounts
won't find it (because routing is done on client side) and returns 404
.
Solution
If you had control over the server, you can serve index.html
for all routes.
This is explained in create react app documentation serving apps with client side routing.
As we don't have that control in case of GitHub pages, We can try these.
Easy Solution
Switch from browserHistory
to hashHistory
With this change, your URLs will go from looking like
www.example.com/myproject/account
to
www.example.com/myproject/#/account
So it's a bit messy.
Harder solution
Get GitHub pages to redirect to index.html
on all requests. Basically you have to add a 404.html
in your build directory with code to redirect to index.html
. More on how to do that.
Create React App has documentation around client-side routing in GitHub pages too
Solution 2:
The best way to solve the issue is create a copy of index.html and call it 404.html for production build. To make it add this to package.json scripts:
"build": "react-scripts build && cp build/index.html build/404.html"