React Vite Github Pages deployment with Router Setup

Michal Kurzewski
3 min readMar 9, 2023

This tutorial should work with any JS framework/library however I tested it with React Vite npm create vite@latest .

I assume you have created Vite project with your preffered settings and it’s aleready pushed to Github

Please refer to my github repository as an example:

https://github.com/MichalKurzewski/gh-pages

  1. Local setup:
  • Add gh-pages package to your project (-D stands for devDependancies location):
npm install gh-pages -D  
  • In your package.jsonunder scripts paste predeploy and deploy lines: (look out only to paste these two lines as other scripts might be different)
  "scripts": {
"dev": "vite", //example line - dont copy paste this
"build": "tsc && vite build", //example line - dont copy paste this
"preview": "vite preview", //example line - dont copy paste this

"predeploy": "npm run build",
"deploy": "gh-pages -d dist"
},
  • In the same file package.jsonmake sure "private": false,
  • In the same file package.json create "homepage": "https://your-github-nick.github.io/name-of-my-repository" . For example:
{
"name": "gh-pages",
"homepage": "https://michalkurzewski.github.io/gh-pages/",
"private": false,

"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
etc.
  • In vite.config.js define base :
export default defineConfig({
base: "/name-of-my-repository/",
plugins: [react()],
});

Make sure you have / at the start and at the end of name of repo string.

Now you are ready to run

npm run deploy

That command will build your project add it dist folder and push it to remote branch named gh-pages . For Router setup read next section. If you dont have it skip to last section.

1.1 Routes refresh 404 issue and workaround:

If your project uses Routes there are few extra steps. It is because Github pages do not fully support SPA, and each refresh of your app in the browser will cause 404 error.

  • To avoid this you need 404.html file in the public directory with content:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Vite + React + TS</title>
<script type="text/javascript">
var pathSegmentsToKeep = 1;
var l = window.location;
l.replace(
l.protocol +
"//" +
l.hostname +
(l.port ? ":" + l.port : "") +
l.pathname
.split("/")
.slice(0, 1 + pathSegmentsToKeep)
.join("/") +
"/?/" +
l.pathname
.slice(1)
.split("/")
.slice(pathSegmentsToKeep)
.join("/")
.replace(/&/g, "~and~") +
(l.search ? "&" + l.search.slice(1).replace(/&/g, "~and~") : "") +
l.hash
);
</script>
</head>
<body></
  • In your index.html you need to add this script above the title :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="text/javascript">
(function (l) {
if (l.search[1] === "/") {
var decoded = l.search
.slice(1)
.split("&")
.map(function (s) {
return s.replace(/~and~/g, "&");
})
.join("?");
window.history.replaceState(
null,
null,
l.pathname.slice(0, -1) + decoded + l.hash
);
}
})(window.location);
</script>
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
  • Finally add a basenameparameter in Router in your main.jsxlike so:
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
import { BrowserRouter as Router } from "react-router-dom";

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<Router basename={"/name-of-my-repository"}>
<App />
</Router>
</React.StrictMode>
);
  • Make sure you deploy again with
npm run deploy

2. Remote setup:

Almost there.

  • Open github.com and go to your repository
  • In Settings go to Pages (under Code and automation), change Branch to gh-pages and press Save
  • You can track the progress of deployment in Github Actions:

And that’s it. Now each time you do a change in your project just redeploy with npm run deloy and everything will run automatically.

https://michalkurzewski.github.io/gh-pages/

--

--