Last active
September 18, 2018 14:44
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html {{htmlAttributes}}> | |
<head> | |
{{headTitle}} | |
{{headMetas}} | |
<!-- etc --> | |
</head> | |
<body {{bodyAttributes}}> | |
<div> | |
{{contents}} | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const helmetUtils = require('./helmetUtils'); | |
metalsmith(__dirname) | |
.source('content') | |
.destination('dist') | |
.use(reactTemplates({ | |
baseFile: 'base.html', | |
isStatic: true, | |
strategy: helmetUtils.strategy, | |
hydrator: helmetUtils.hydrator, | |
[...] | |
})) | |
[...] |
Hey, sorry, didn't see your comment. I should have something working, somewhere... I'll try to check this in the coming days ;)
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.
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
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!