Security News
PyPI’s New Archival Feature Closes a Major Security Gap
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
react-router-template
Advanced tools
Provides a universal solution to rendering a react-router hierarchy on both the server and the client.
Quickly render universal react-router components using a simple API.
// Server
import template from 'react-router-template';
const render = template({
routes,
wrapHtml: html => `<!DOCTYPE HTML>${html}`,
wrapComponent: component => (
<Provider store={store}>
{component}
</Provider>
)
});
app.get('*', (req, res) => {
render(req).then(html => res.end(html));
});
// Browser
import template from 'react-router-template';
const render = template({
routes,
wrapComponent: component => (
<Provider store={store}>
{component}
</Provider>
)
});
render(document.getElementById('container'))
.then(() => console.log('rendering complete'));
react-router-template
is a universal solution to rendering a react-router hierarchy on both the server and the browser.
Simply provide a template on how to render components with the option to alter the output as you like, then use the returned render
function to either output a string (on the server) or mount on the DOM (in the browser). Common alterations to the output are wrapping it in a <Provider>
or prepending a <!DOCTYPE>
.
Server-side templates are defined with the following options:
routes
- the <Route>
hierarchy required for react-router to match against and render. Supports async routescreateElement
- optional function passed to the <RouterContext>
wrapComponent
- optional function that is passed the resulting <RouterContext>
, allowing you to wrap / compose it in Providers (e.g. react-redux's <Provider>
) or other additional React componentswrapHtml
- optional function that allows you to decorate the resultant HTML stringBoth wrapComponent
and wrapHtml
are evaluated as Promise
s, and thus can be either synchronous or asynchronous.
import template from 'react-router-template';
import { Route } from 'react-router';
import { Provider } from 'react-redux';
import { App, Index } from './components'; // or wherever you place them
const routes = (
<Route path="/" component={App}>
<Route path="/index" component={Index} />
</Route>
);
// most basic use case
const render = template({ routes });
// using more options
const anotherRender = template({
routes,
wrapHtml: html => `<!DOCTYPE HTML>${html}`,
wrapComponent: component => (
<Provider store={store}>
{component}
</Provider>
)
});
The output is a render() function that returns a Promise resolving into a string:
// assuming an express route
app.get('*', (req, res) => {
render(req).then(html => res.end(html));
});
In the example above, the req
object is passed in directly, but:
originalUrl
property is sufficient.// both of these will work
render('/some-path');
render({ originalUrl: '/some-path'});
When the path specified cannot be found or redirects, the render
function will throw an Error
with the following properties:
.status
or statusCode
will be a number, 404
for not found, 302
for redirects..location
or .url
will also be present to allow the developer to take the appropriate actionapp.get('*', (req, res) => {
render(req)
.then(html => res.end(html))
.catch(err => {
const { status, location } = err;
if (status === 404) {
// handle not found
} else if (status === 302) {
res.redirect(location);
} else {
// other error handling
}
});
});
Browser templates are defined with the following options:
routes
- the <Route>
hierarchy required for react-router to match against and render. Supports async routescreateElement
- optional function passed to the <RouterContext>
wrapComponent
- optional function that is passed the resulting <RouterContext>
, allowing you to wrap / compose it in Providers (e.g. react-redux's <Provider>
) or other additional React componentswrapComponent
is evaluated as a Promise
and thus can be either synchronous or asynchronous.
import template from 'react-router-template';
import { Route } from 'react-router';
import { Provider } from 'react-redux';
import { App, Index } from './components'; // or wherever you place them
// most basic use case
const render = template({
routes
});
// using more options
const render = template({
routes,
wrapComponent: component => (
<Provider store={store}>
{component}
</Provider>
)
});
The resulting render()
is a promise-returning function that takes up to 2 arguments, rather than just one. Instead of a path (or an object containing originalUrl
):
history
object (or object containing a history
property).// some client JS entry point
import { browserHistory } from 'react-router';
const target = document.getElementById('container');
render(browserHistory, target)
.then(() => console.log('rendering complete'));
If the history object is not specified (i.e. only one argument, the target
, is supplied), then it is assumed that react-router
's browserHistory
will be used.
// both of these will work
render({ history: browserHistory}, target);
render(target);
This reflects the nature of client-side rendering - the path is usually determined from the browser context rather than being supplied, and the second argument matches React's own render
signature.
NOTE: There is no wrapHtml
option, because on the browser React is primarily concerned with mounting the component onto an existing DOM, not producing any HTML string output.
There is no special API for errors on the browser, apart from the fact that any error is caught as a Promise rejection.
Redirects are handled automatically on the browser for you via the supplied history object.
Any errors created are no different than if you weren't using react-router-template, but just React's native .render()
method.
render(browserHistory, target)
.catch(err => console.error(err));
Bundlers are expected to use the entrypoint specified by browser
in this module's package.json
as per the specifications outlined here
FAQs
Provides a universal solution to rendering a react-router hierarchy on both the server and the client.
We found that react-router-template demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now allows maintainers to archive projects, improving security and helping users make informed decisions about their dependencies.
Research
Security News
Malicious npm package postcss-optimizer delivers BeaverTail malware, targeting developer systems; similarities to past campaigns suggest a North Korean connection.
Security News
CISA's KEV data is now on GitHub, offering easier access, API integration, commit history tracking, and automated updates for security teams and researchers.