Ok, so I've made a SPA using React and React-Router and have pushed it to github pages, but none of the routes I have written work when I refresh or click back in my browser. I had the same problem when I was serving the page locally, but then followed along to this SO answer and made a server.js file which provided a redirect to my static HTML page at each route. Here is what the file looks like:
"use strict";
let express = require('express');
let path = require('path');
let app = express();
app.use(express.static('public'));
app.get('/contact', function(req, res){
res.sendFile('public/index.html', { root: __dirname });
})
app.get('/about', function(req, res){
res.sendFile('public/index.html', { root: __dirname });
})
app.get('*', function(req, res){
res.sendFile('public/index.html', { root: __dirname });
})
app.listen(8080, function(){
console.log('Listening on port 8080!')
})
Now, my problem is that when I push the project to github pages all of that logic is ignored, github's routing takes over and I have the same problem of not being able to refresh or go straight to /contact
or /about
. I know it seems like an obvious problem to run into, since github pages is designed to only host static sites, but I've seen people hinting towards other ways of creating a static page for each route, such as the answer in this reddit post, but I have no idea how to do that.
I should also mention that because I already have a site at user-name.github.io
, so this site is being hosted at user-name.github.io/projects
, making that my /
route. I have no idea if this makes any difference, I just thought I should mention it.
I think I've pretty much exhausted every option to try and successfully host this on gh-pages and I know there are projects like Single Page Apps for GitHub Pages to try and fix this issue but, I just wanted to see if anyone out there has had any luck doing this before resorting to that.
FYI, here is my app.js (containing routing logic):
import React, {Component} from 'react';
import {render} from 'react-dom';
import {Router, Route, browserHistory, IndexRoute} from 'react-router';
//Import custom components
import About from '../components/about.js';
import Contact from '../components/contact.js';
import Sidebar from '../components/sidebar.js';
import Imagelist from '../components/image-list.js';
render(
<Router history={browserHistory}>
<Route path="/" component={Sidebar}>
<IndexRoute component={Imagelist}/>
<Route path="/about" component={About}/>
<Route path="/contact" component={Contact}/>
</Route>
</Router>,
document.getElementById('content')
);
Any help with this would be much appreciated & happy to include more code if helpful.
Ok, so I've made a SPA using React and React-Router and have pushed it to github pages, but none of the routes I have written work when I refresh or click back in my browser. I had the same problem when I was serving the page locally, but then followed along to this SO answer and made a server.js file which provided a redirect to my static HTML page at each route. Here is what the file looks like:
"use strict";
let express = require('express');
let path = require('path');
let app = express();
app.use(express.static('public'));
app.get('/contact', function(req, res){
res.sendFile('public/index.html', { root: __dirname });
})
app.get('/about', function(req, res){
res.sendFile('public/index.html', { root: __dirname });
})
app.get('*', function(req, res){
res.sendFile('public/index.html', { root: __dirname });
})
app.listen(8080, function(){
console.log('Listening on port 8080!')
})
Now, my problem is that when I push the project to github pages all of that logic is ignored, github's routing takes over and I have the same problem of not being able to refresh or go straight to /contact
or /about
. I know it seems like an obvious problem to run into, since github pages is designed to only host static sites, but I've seen people hinting towards other ways of creating a static page for each route, such as the answer in this reddit post, but I have no idea how to do that.
I should also mention that because I already have a site at user-name.github.io
, so this site is being hosted at user-name.github.io/projects
, making that my /
route. I have no idea if this makes any difference, I just thought I should mention it.
I think I've pretty much exhausted every option to try and successfully host this on gh-pages and I know there are projects like Single Page Apps for GitHub Pages to try and fix this issue but, I just wanted to see if anyone out there has had any luck doing this before resorting to that.
FYI, here is my app.js (containing routing logic):
import React, {Component} from 'react';
import {render} from 'react-dom';
import {Router, Route, browserHistory, IndexRoute} from 'react-router';
//Import custom components
import About from '../components/about.js';
import Contact from '../components/contact.js';
import Sidebar from '../components/sidebar.js';
import Imagelist from '../components/image-list.js';
render(
<Router history={browserHistory}>
<Route path="/" component={Sidebar}>
<IndexRoute component={Imagelist}/>
<Route path="/about" component={About}/>
<Route path="/contact" component={Contact}/>
</Route>
</Router>,
document.getElementById('content')
);
Any help with this would be much appreciated & happy to include more code if helpful.
Share Improve this question edited Jun 16, 2017 at 14:03 laser 1,37613 silver badges14 bronze badges asked Nov 24, 2016 at 1:13 Maxine EllahMaxine Ellah 2054 silver badges11 bronze badges 2- express is a backend framework to write api routes... what do you trying to achieve with gh static pages? you want to gh page points to a api in another domain? – Lucas Katayama Commented Nov 24, 2016 at 3:00
- I used express because that was what was suggested in another SO answer, but yes, I know I can't include any of this logic when I push it to gh-pages. Just trying to see if there is any advice on creating a static page for each route. – Maxine Ellah Commented Nov 24, 2016 at 21:57
5 Answers
Reset to default 9I think you need to change your browserHistory to a hashHistory.. so you can use it with gh... it changes path from /home to #/home
Aside from using hashHistory
as suggested in the accepted answer, there is another workaround. Look here.
Basically, you create a spoof 404.html
file which has a script that converts the requested path into the query string & redirects the browser to the index page with the query string attached to the URL. After the index file is loaded, the original path is restored from the query string & ReactRouter
picks up the changes.
A neat solution, but not production-ready, either.
If you are using create-react-app (I haven't tested this in any other environment) you can use browserRouter
, you will need to pass a basename
prop to the component with this env variable: process.env.PUBLIC_URL
.
Your router should now look like this:
<BrowserRouter basename={process.env.PUBLIC_URL}>
{/* routes */}
</BrowserRouter>
For more info you can checkout this Github thread
Use process.env.PUBLIC_URL in your route definitions so that they work both in development and after deployment. For example: . This will be empty in development and ... (inferred from homepage) in production.
To extend Jildert's answer, I did the same - copied index.html to 404.html before deploying to the github pages and it worked.
So I've just updated pre-deploy section of package.json to include this copy action and now it works fine with BrowserRouter:
"predeploy": "npm run build && cp build/index.html build/404.html",
"deploy": "gh-pages -d build"
I just found a solution for this without using the HashRouter. I created a little node script that's called before my deployment script that creates a 404.html file with the same content as the index.html. Github pages serves that file if you refresh on a page in your react-app.
const fs = require('fs')
fs.copyFile('build/index.html', 'build/404.html', (err) => {
if (err) throw err
console.log('index.html was copied to 404.html')
})