Reputation: 10052
This is my main app file:
import React from 'react';
import { render } from 'react-dom';
import { browserHistory, Router, Route, IndexRoute } from 'react-router';
// Components
import Main from './components/core/Main.component';
import NotFound from './components/core/NotFound.component';
import About from './components/About.component';
import TeaTimer from './components/TeaTimer.component';
// App css
require('style!css!sass!applicationStyles');
render(
(<div>
<Router history={browserHistory}>
<Route component={Main} path="/">
<IndexRoute component={TeaTimer} />
<Route component={About} path="/about"/>
</Route>
<Route component={NotFound} path="*"/>
</Router>
</div>),
document.querySelector('#app')
);
This is my Main component:
import React, { Component } from 'react';
class Main extends Component {
render() {
return (
<div>
{this.props.children}
</div>
)
}
}
Main.propTypes = {
children: React.PropTypes.object
}
export default Main;
This is my express server setup:
var express = require('express');
// Create our app
var app = express();
const PORT = process.env.PORT || 3000;
app.use(function (req, res, next){
if (req.headers['x-forwarded-proto'] === 'https') {
res.redirect('http://' + req.hostname + req.url);
} else {
next();
}
});
app.use(express.static('public'));
app.listen(PORT, function () {
console.log('Express server is up on port ' + PORT);
});
Now when I open the browser and go to http://localhost:3000
I get the TeaTimer component. Same for http://localhost:3000/#/
, same for http://localhost:3000/#/about
, same for an undefined route - http://localhost:3000/#/sdnaipwnda[j
.
But when I go to http://localhost:3000/about
I get:
Cannot GET /about
What am I doing wrong?
If you need more info please ask and I will add it to the question, or checkout this git repo.
Upvotes: 2
Views: 1247
Reputation: 1643
no need to have / inside about path.
render(
(<div>
<Router history={browserHistory}>
<Route component={Main} path="/">
<IndexRoute component={TeaTimer} />
<Route component={About} path="about" />
</Route>
<Route component={NotFound} path="*" />
</Router>
</div>),
document.querySelector('#app')
);
Upvotes: 0
Reputation: 14473
OK, this one is straightforward. You're simply using the wrong history. You need hashHistory
if you want to have hash-based, i.e. /#/about
and such, routes.
import {Router, hashHistory} from 'react-router'
...
<Router history={hashHistory}>
...
If you DON'T want a hash-based history, but would rather like regular-looking URL's, like /about
and such, then you DO need browserHistory
. However, in this case you MUST make sure that your web server serves the same index.html
for all route-like URL's. This is explained in the react-router
' documentation. You need to add something like this towards the end of your express server's routing configuration:
// handle every other route with index.html, which will contain
// a script tag to your application's JavaScript file(s).
app.get('*', function (request, response){
response.sendFile(path.resolve(__dirname, 'public', 'index.html'))
})
The above code assumes that your index.html file lies in public/
, so you might need to change the arguments to path.resolve
.
I actually prefer returning index.html only for URL's that don't have an extension. This way you prevent your index.html being served as a .png or .js whenever the requested resource is missing and you get a meaningful 404 instead.
app.get('*', function (request, response){
if (request.path.match(/\/[^\/.]*$/)) {
response.sendFile(path.resolve(__dirname, 'public', 'index.html'))
}
})
Upvotes: 1
Reputation: 4561
remove /
from path
<Route component={About} path="about"/>
remove
Main.propTypes = {
children: React.PropTypes.object
}
anyway children are passed as props by default
Upvotes: 0