React Vite Github Pages deployment with Router Setup
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:
- Local setup:
- Add gh-pages package to your project (-D stands for devDependancies location):
npm install gh-pages -D
- In your
package.json
under 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.json
make 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
definebase
:
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 thetitle
:
<!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
basename
parameter inRouter
in yourmain.jsx
like 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.