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,
[...]
}))
[...]
@varya
Copy link

varya commented Jun 22, 2018

Hi Leimi. Do you probably have this example working in some metalsmith instance? I'm trying to use it in my repo but get empty properties. It would help if I could run your repo and compare how it works for you. Thank you very much!

@manuhabitela
Copy link
Author

Hey, sorry, didn't see your comment. I should have something working, somewhere... I'll try to check this in the coming days ;)

@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