Important
Relies on PR webpack/style-loader#159 in style-loader.
Or use temp npm package of forked version - @humblespark/style-loader
style-loader can't work server side the same way it does client side, because there is no global document / object
to write styles to. to collect critical styles on server, we need style-loader to expose the generated css, for us
to bubble up to a higher order component for initial server side render. we need style-loader to expose locals
as css-loader does.
addCriticalStyles- hocaddCriticalStyles(styles)(App)RemoveCriticalStyles- optional component for clientGatherCriticalStyles- wrap server components to gather critical stylesstringifyStyles- helper to join & minify styles to put in head
server.js (gathers styles from components to render inline in head)
import { GatherCriticalStyles, stringifyStyles } from 'react-ssr-critical-styles';
...
let criticalStyles = [];
const content = renderToString(
<GatherCriticalStyles addCriticalStyles={(s) => criticalStyles.push(s)}>
<App />
</GatherCriticalStyles>
);
res.status(200).send(template(content, stringifyStyles(criticalStyles)));
...client.js (optionally removes styles once style-loader kicks in on client. using this is optional.)
import { RemoveCriticalStyles } from 'react-ssr-critical-styles';
...
render((
<RemoveCriticalStyles styleId="critical-styles">
<App />
</RemoveCriticalStyles>
), document.getElementById('root'));
...AppComponent.js (addCriticalStyles hoc uses context to bubble up through component tree.)
import React, { Component } from 'react';
import styles, { locals } from 'app.css';
import { addCriticalStyles } from 'react-ssr-critical-styles';
class App extends Component {
render() {
return <div className={locals.App} />
}
}
export default addCriticalStyles(styles)(App);