Deploy React To Github Pages

Deploy React To Github Pages

Reading time1 min
#React#Development#Web#GitHubPages#ReactDeployment

Mastering React Deployment on GitHub Pages: Professional Practices

React applications often get hosted on cloud providers, but for individual portfolios or lightweight demos, GitHub Pages remains highly effective—despite skepticism about its suitability for complex SPAs. With correct configuration, you’ll sidestep pathing issues, enjoy zero operational cost, and reduce deployment friction to a single command.


Why Bother with GitHub Pages for React?

StrengthDetail
CostFree static hosting, no bandwidth charges
AvailabilityServed via GitHub CDN with auto HTTPS
Custom DomainsSupported out of the box, including DNS and LetsEncrypt
Public VisibilityIdeal for live demos and CVs; no infra to maintain

Side note: For apps requiring server-side API integrations, the lack of backend limits applicability. For pure frontend portfolios, it remains unbeaten in simplicity.


1. Prepare the React App

Generate a new React app with Create React App (CRA) 5.x or later:

npx create-react-app@5.0.1 my-react-app
cd my-react-app

Production readiness check: Remove unfinished code, commit only the final static assets.


2. Specify Deployment Subpath

Without correctly setting "homepage", asset paths break, especially if your repo name differs from your app name or when using organization accounts.

In package.json:

"homepage": "https://<github-username>.github.io/<repository-name>"

If deploying to a custom domain, replace with "https://yourdomain.com".


3. Automate Builds & Deployment

Install the gh-pages package:

npm install --save-dev gh-pages@4.0.0

In package.json, configure scripts precisely. Overriding pre-existing deploy scripts is common after experimentation:

"scripts": {
  "predeploy": "npm run build",
  "deploy": "gh-pages -d build",
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test"
}
  • predeploy: Ensures a fresh production bundle.
  • deploy: Pushes build output to the gh-pages branch.

4. GitHub Integration

Initialize git, commit the app, push to remote.

git init
git remote add origin https://github.com/<username>/<repository>.git
git add .
git commit -m "Initial commit"
git branch -M main
git push -u origin main

Replace remote if already set, see git remote -v.


5. Run Deployment

The sequence:

npm run deploy
  • Bundles to /build
  • Publishes to the gh-pages branch
  • Sets up the static site for GitHub Pages

Check the GitHub Actions log: if the action is blocked (e.g., “gh-pages branch is protected”), adjust branch protection rules or permissions.


6. GitHub Pages Configuration

Repository → Settings → Pages:

  • Set source branch: gh-pages, directory: / (root)
  • Click “Save”
  • Confirm published URL. Usually matches the homepage value.

Note: It can take a few minutes for DNS/CDN propagation.


Routing, Broken Links, and Rendering Issues

A typical React gotcha: refreshing on a subpath (e.g., /about) leads to a 404. GitHub Pages serves only static files, no rewrite to index.html happens.

Mitigations:

  • Use HashRouter in place of BrowserRouter:

    import { HashRouter } from 'react-router-dom';
    export default function App() {
      return (
        <HashRouter>
          {/* ...routes */}
        </HashRouter>
      );
    }
    

    Downside: URLs include the # symbol (example: /#/about).

  • Advanced: Place a custom 404.html in /public that redirects all unmatched requests to /index.html. See rafgraph/spa-github-pages for a reference implementation. Caveat: Subtle issues for apps with unusual routing bases.

Known Issue: Sometimes the first deployment stalls with “Page not found”. Check CNAME clashes, repository visibility (public), and clear browser cache if URL keeps returning old content.


Practical Example: package.json Excerpt

{
  "name": "my-react-app",
  "version": "0.1.0",
  "private": true,
  "homepage": "https://johndoe.github.io/my-react-app",
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.12.1"
  },
  "devDependencies": {
    "gh-pages": "^4.0.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build"
  }
}

Non-obvious Tips

  • Lock gh-pages version: New releases sometimes change default behavior; builds may fail silently.
  • If you need environment variables (REACT_APP_*), ensure they’re valid at build time. Secrets will not be available at runtime on GitHub Pages.
  • For CI/CD: Add a GitHub Actions workflow to automate pushing to gh-pages on main update—removes need for local deploys.

Documents like this can make the difference between a clean, live portfolio and “project not found”. GitHub Pages isn’t for everyone, but for static React apps, with mindful routing setup and correct asset pathing, it’s robust and nearly effortless.

Got a more complicated multi-branch scenario? Consider pushing multiple apps to different subdirectories using a mono-repo and customizing gh-pages -d build/subdir. But that’s another layer—keep it simple unless you need that flexibility.