koa 2 middleware for React server side rendering and routing with react-router.
To install koa-react-router
:
npm install koa-react-router react react-dom react-router --save
Note:
react
react-dom
&react-router
are allpeerDependencies
ofkoa-react-router
. This allows your application to easily keep up to date with the latest versions of the frameworks.
koa-react-router
can be mounted easily in a koa 2 application like so:
// index.js
import Koa from 'koa';
import reactrouter from 'koa-react-router';
import routes from './routes';
import Container from './containers/PageContainer';
import RouterContainer from './containers/RouterContainer';
const app = new Koa();
app.use(reactrouter({
routes,
onError: (ctx, err) => console.log('I Have failed!!!!'),
onRedirect: (ctx, redirect) => console.log('I have redirected!'),
onNotFound: (ctx) => console.log('Not Found!!!'),
onRender: (ctx) => ({ Container, RouterContainer })
}));
koa-react-router
requires the following parameters:
The react-router
routes to use for the application. For example:
// routes.js
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import Home from '../containers/Home';
import Article from '../containers/Article';
module.exports = (
<Route path="/">
<IndexRoute component={Home} />
<Route path="/article" component={Article} />
</Route>
);
// index.js
// ...imports
import routes from './routes';
// ... koa app setup
app.use(reactrouter({
routes: routes,
// Other callbacks
}));
Callback function called when an error occurs whilst route matching.
The function accepts the following parameters:
ctx
- The KoaContext
object.err
- The error that occured whilst route matching. See react-router docs for more details.
Callback function called if the route is match to a redirect.
The function accepts the following parameters:
ctx
- The KoaContext
object.redirect
- The Location object for the route. See react-router docs for more details.
Callback function called if no route matches the requested url.
The function accepts the following parameters:
ctx
- The KoaContext
object.
Callback function called before rendering a route.
This function must be supplied, and must return an object that contains the following property:
This should be a React component that wraps around the rendered route.
Typically this will be the template for the page, however this is not mandatory.
As such this component is rendered using renderToStaticMarkup
.
The component must accept the children
prop and insert it when rendered.
For example:
// ./containers/Container
import React from 'react';
const Container = (props) =>
<html lang="en">
<head>
<title>Hello Container</title>
</head>
<body>
<div id="app">
{props.children}
</div>
</body>
</html>;
export default Container;
This would then be supplied to koa-react-router
via the onRender
callback like so:
// index.js
import Koa from 'koa';
import reactrouter from 'koa-react-router';
import routes from './routes';
import Container from './containers/Container';
const app = new Koa();
app.use(reactrouter({
routes,
onRender: (ctx) => ({ Container })
}));
As well as the Container
property this callback can optionally return:
Optional React component that is immediatley wrappered around the routes.
If supplied this component will sit between the Container
component and the routes
.
For example:
<Container>
<RouterContainer>
{routes}
</RouterContainer>
</Container>
As such this component is rendered using renderToString
meaning it has the react attributes it would have when rendered in a browser.
The component must accept the children
prop and insert it when rendered.
Full example:
// ./containers/RouterContainer
import React from 'react';
const RouterContainer = (props) =>
<div>
<p>Hello routes</p>
{props.children}
</div>;
export default RouterContainer;
This would then be supplied to koa-react-router
via the onRender
callback like so:
// index.js
import Koa from 'koa';
import reactrouter from 'koa-react-router';
import routes from './routes';
import Container from './containers/Container';
import RouterContainer from './containers/RouterContainer';
const app = new Koa();
app.use(reactrouter({
routes,
onRender: (ctx) => ({ Container, RouterContainer })
}));
This component could also be a Provider
containing a redux
store.
A full example when using redux is coming soon.
Optional function for handling the rendering of a container component.
This function has one argument which is view
. This argument is the currently rendered view from the Router.
This function may be used if some custom props need to be injected into the container component, such as an initial Redux state.
This function should be used instead of the Container
property when returning from onRender
.
For example you may want to render the conatiner as follows:
// index.js
import Koa from 'koa';
import reactrouter from 'koa-react-router';
// ...other imports
const app = new Koa();
const state = // Create state.
app.use(reactrouter({
routes,
onRender: (ctx) => ({
containerRenderer: (view) =>
<html lang="en">
<head>
<script dangerouslySetInnerHTML={{ __html: state}} />
</head>
<body>
<p>hello container</p>
<div dangerouslySetInnerHTML={{ __html: view }} />
</body>
</html>
})
}));
The final page render would look something like:
<html lang="en">
<head>
<script>//State config</script>
</head>
<body>
<p>hello container</p>
<div>
<!-- View html in here -->
</div>
</body>
</html>