I recently deployed an app made with Create React App to GitHub Pages. I ran into a problem getting the build assets to be served correctly and thought this quick post might help someone who runs into the same issue.
tldr: change the
homepage
inpackage.json
from[username].github.io/[project]
to your custom domain so that the build assets are served at root rather than at/[project]
This post assumes you have a working User Project Page at [username].github.io/[project]
. If your app is at the default user page - [username].github.io
- you won't have this problem.
The GitHub Help docs are very thorough, and you should not have much of a problem configuring your DNS records or adding a custom domain to your repo settings. I added the custom subdomain www.[site].[domain]
to the settings in my project repo. I then set up an apex domain and www
subdomain by adding 4 A records pointing to GitHub's IP addresses and a CNAME record for the www
subdomain pointing to [username].github.io
. You may configure your records differently, but as long as your (sub)domain is pointing to your project page, the rest of this post will still be relevant if you can't get your assets served.
Note: If you are using the gh-pages package to push your build folder to the gh-pages branch of your repo, it will overwrite the CNAME record added to that branch when you entered your custom domain on the settings page. I added
www.[site].[domain]
to aCNAME
file in thepublic
folder of my master branch. That way Create React App adds it to the build.
I thought that is all I would have to do to get my domain working. But when I went to www.[site].[domain]
, the page didn't load. Checking the console showed that my index.html
was served, so my DNS records with GitHub and my domain provider were working. But the script tags pointed to /[project]/static
rather than just /static
. Similarly, the page was looking for my favicon at /[project]
rather than root. Why had the build been correctly served at [username].github.io/[project]
only to break after adding my custom domain?
The problem is that Create React App creates an environment variable, PUBLIC_URL
, to set the path to assets. And, crucially, it uses the homepage
value in package.json
to determine if any subdirectories should be prepended to paths. When the site was at [username].github.io/[project]
, having homepage
set to that url didn't cause a problem because the build folder was located at /[project]
. The page would look for assets at /[project]/static
, for example, and they were there.
But when the site moved to www.[site].[domain]
, the build folder became located at root. The page was still looking for assets at /[project]/static
, but there wasn't a /[project]
directory in the build folder, obviously.
Changing the homepage
in package.json
from [username].github.io/[project]
to the custom domain now causes the page to look for assets in the right place, and the site loads.
In fact, I think you can set
homepage
to any url that doesn't contain subdirectories (assuming your build is at root) and it will work - though that's obviously a bad idea for other reasons.
This is another quirk of GitHub serving your page at a subdirectory.
Top comments (3)
You can use react-snap as well, to prerender CRA pages as well especially helpful if you use router, otherwise you will get 404 when you refresh page in non-root path
Interesting - thanks for letting me know. I'm using hash router to avoid that problem now, but I always think it looks weird.
Incredibly helpful. Thank you!