I'm creating a website that will have the following:
I'm using react-router ^3.0.0
, react-router-redux ^4.0.7
, and webpack 2.1.0-beta.20
in the site. I'm trying to set up my routes like so:
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import thunk from 'redux-thunk';
import {Router, Route, browserHistory} from 'react-router';
import {combineReducers, createStore, applyMiddleware} from 'redux';
import {Provider} from 'react-redux';
import {routerReducer, syncHistoryWithStore} from 'react-router-redux';
import {IntlProvider, intlReducer} from 'react-intl-redux';
import {addLocaleData} from 'react-intl';
import en from 'react-intl/locale-data/en';
import {Home} from './app/components/Home/Home';
import Profile from './app/components/Profile/Profile';
import Login from './app/components/Login/Login';
import SignUp from './app/components/SignUp/SignUp';
import Items from './app/components/Items/Items';
import Item from './app/components/Item/Item';
import {requireAuthentication} from './app/components/General/AuthenticatedComponent';
import {reducers} from './app/reducers/reducers';
import {i18n} from './app/i18n/i18n';
import './index.scss';
addLocaleData([
...en
]);
// Create the store from the reducers
const store = createStore(combineReducers({
reducers,
routing: routerReducer,
intl: intlReducer
}), i18n, applyMiddleware(thunk));
// Create an enhanced history that syncs navigation events with the store
const history = syncHistoryWithStore(browserHistory, store);
ReactDOM.render(
<Provider store={store}>
<IntlProvider locale="en" defaultLocale="en">
<Router history={history}>
<Route path="/" component={Home}/>
<Route path="/profile" component={requireAuthentication(Profile, true)}/>
<Route path="/login" component={requireAuthentication(Login, false)}/>
<Route path="/signup" component={requireAuthentication(SignUp, false)}/>
{/* Items route lists all of the items, Item shows details for one individual item */}
<Route path="/items" component={Items}/>
<Route path="/items/:itemId" component={Item}/>
</Router>
</IntlProvider>
</Provider>,
document.getElementById('root')
);
The Items
and Item
components are unrelated, and do not depend on each other.
When I navigate to http://localhost/items
, the Items
component renders. But when I navigate to http://localhost/items/1
, nothing renders, and I get the following error in the console:
GET http://localhost:3000/items/index.js
I've tried to fix this a few ways, each resulting in the same error message
...
<Route path="/items" component={Items}/>
<Route path="/items/:itemId" component={Item}/>
...
...
<Route path="/items" component={Items}>
<Route path="/:itemId" component={Item}/>
</Route>
...
...
<Route path="/items">
<IndexRoute component={Items}/>
<Route path="/:itemId" component={Item}/>
</Route>
...
I am able to get the Item
component to render with the param when I do this though
...
// Navigate to http://localhost:3000/1
<Route path="/:itemId" component={Item}/>
...
But that's not how I want the URLs to be set up. Does anyone know how to fix this problem? Thanks for the help!
So it turns out that this was not a react-router
problem, but instead a webpack
problem. I took a look at the source code that was being compiled, and it looked like this
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link href="https://fonts.googleapis.com/css?family=Lato:300,400,7s00" rel="stylesheet">
<link rel="icon" type="image/png" href="http://fountainjs.io/assets/imgs/fountain.png" />
<title>My Web App</title>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.2/semantic.min.css></link>
</head>
<body>
<!-- Entry point for the application -->
<div id="root"></div>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
The index.js
file should be linked as /index.js
, otherwise it looks in the current directory that the route is in. So in my webpack.conf.js
file, I found a section that mentions index.js
output: {
path: path.join(process.cwd(), conf.paths.tmp),
filename: 'index.js'
}
I simply changed it to
output: {
path: path.join(process.cwd(), conf.paths.tmp),
filename: '/index.js'
}
And it worked. The index.js
file is now linked properly in the source