Skip to content

Instantly share code, notes, and snippets.

@manuhabitela
Last active September 18, 2018 14:44
Show Gist options
  • Save manuhabitela/b62975a28b202fb6919fa7feb7688f5b to your computer and use it in GitHub Desktop.
Save manuhabitela/b62975a28b202fb6919fa7feb7688f5b to your computer and use it in GitHub Desktop.
metalsmith-react-templates example of a custom strategy & hydrator for React Helmet server-side rendering
<!DOCTYPE html>
<html {{htmlAttributes}}>
<head>
{{headTitle}}
{{headMetas}}
<!-- etc -->
</head>
<body {{bodyAttributes}}>
<div>
{{contents}}
</div>
</body>
</html>
const React = require('react');
const reactTemplates = require('metalsmith-react-templates/jsx-render-engine/strategy/react').default;
const Helmet = require('react-helmet').Helmet;
function strategy(props = {}, options = {}, templateReader = null) {
const markupPromise = reactTemplates(props, options, templateReader);
const helmet = Helmet.renderStatic();
const helmetProps = {
'bodyAttributes': helmet.bodyAttributes.toString(),
'htmlAttributes': helmet.htmlAttributes.toString(),
'headLinks': helmet.link.toString(),
'headMetas': helmet.meta.toString(),
'headStyles': helmet.style.toString(),
'headTitle': helmet.title.toString()
};
// this will break if not using a custom hydrator!
// because the default hydrator assumes that the strategy
// returns the markup string and not an object
return markupPromise.then(markup => ({
contents: markup,
helmet: helmetProps
}));
}
function hydrator(originalData, strategyContent) {
return {
...originalData,
...strategyContent.helmet,
contents: new Buffer(strategyContent.contents)
);
};
module.exports = {
strategy,
hydrator
};
const helmetUtils = require('./helmetUtils');
metalsmith(__dirname)
.source('content')
.destination('dist')
.use(reactTemplates({
baseFile: 'base.html',
isStatic: true,
strategy: helmetUtils.strategy,
hydrator: helmetUtils.hydrator,
[...]
}))
[...]
@manuhabitela
Copy link
Author

manuhabitela commented Jun 26, 2018

I realize this example is obsolete. The hydrator should be tied to the postRenderHydrator option, not hydrator. Did you try that?

Besides that, checking quickly my code (that I can't show you that easily for now, sorry), it seems what I do in the example and in my working code is the same.

@manuhabitela
Copy link
Author

I realized just today, when using this again, that the stable release of metalsmith-react-templates wasn't up-to-date with master and didn't include this. You might want to build the master branch yourself locally and give it a try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment