Hello, when building react projects wih CRA, everything that a modern frontend development has to offer is present: support for a development server, modules hot reload, tooling support and a testing library.
There is, however, a few important steps to perform in order to go from development mode to production.
In this article we'll point out a few issues when using github pages as a hosting solution for the app.
Publishing a static site at github pages is cool because it's mostly GitOps: commit is publish, and github pages now use github actions workflows to deploy your site:
The default deploy action, however, tries to deploy the root directory of your project; back in time, it was the default method to deploy something using github pages, but now there are actions. Use this customized action to properly deploy your CRA application:
# .github/workflows/gh-page-deploy.yml
# best approach to use this configuration is to go first into
# github pages project settings, select github action to publish
# and then replace the offered action by this one.
name: build and deploy gh-pages
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
strategy:
matrix:
node-version: [18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- name: Setup Pages
uses: actions/configure-pages@v3
# make sure to point to the build folder produced by previous build step
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
path: './build'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
And that's it, every push to the main branch will run the action and will publish the app.
However...
It happens because CRA builds to be in the root directory of you site.
Github pages, by default, are not.
To fix that, CRA documentation suggest to add the homepage attribute into your package.json file.
And this is a good enough solution.
Unless...
If you project uses react router, History push navigation most likely will replace the uri part which is your project from the site url.
CRA build itself went well, but router dom isn't aware of that homepage configuration.
To resolve that, you can set the basename attribute on your route.
But then...
Since locally, in development mode, you do run at root site context, basename
will mess with your developer experience. What a ride, huh?
A little dig and a better solution pop out.
CRA has good support for dotenv-flow configurations out of the box.
Make use of .env.development
and .env.production
env files and set these two
variables:
# .env.development
PUBLIC_URL=/
REACT_APP_URI=/
# .env.production
PUBLIC_URL=https://sombriks.github.io/react-studies/
# to make react router behave
REACT_APP_URI=/react-studies
And edit your router to point to the specified uri:
// some imports
function App() {
return (
<Router basename={process.env.REACT_APP_URI}>
// the rest of tye component
But it happens...
No, just kidding, this time you're good to develop and to deploy.
This small tweak is one of those things you do and forget, so it's nice to keep it recorded somewhere, just in case you need it in the future.
You can find the source code sampling this solution here.
Happy hacking.