Skip to content

Instantly share code, notes, and snippets.

@danneu
Last active November 21, 2017 22:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danneu/c2b35c49b94b77b2a2ba02905959bb10 to your computer and use it in GitHub Desktop.
Save danneu/c2b35c49b94b77b2a2ba02905959bb10 to your computer and use it in GitHub Desktop.
// Middleware function creates a `ctx.render('homepage', { title, foo })`
// function on the koa context.
const reactRenderware = (root, _opts = {}) => {
const defaultOpts = () => ({ locals: {} })
const { locals: globals, opts } = { ...defaultOpts(), ..._opts }
const { extname } = require('path')
const React = require('react')
const ReactDOMServer = require('react-dom/server')
const Master = require(path.join(root, 'master.jsx'))
return async (ctx, next) => {
ctx.render = (templatePath, locals) => {
const fullpath = path.join(
root,
extname(templatePath) ? templatePath : templatePath + '.jsx'
)
const Template = require(fullpath)
ctx.type = 'html'
const output = new (require('stream')).PassThrough()
output.write('<!doctype html>')
ReactDOMServer.renderToStaticNodeStream(
<Master {...globals} {...locals} ctx={ctx}>
<Template {...locals} ctx={ctx} />
</Master>
).pipe(output)
ctx.body = output
}
return next()
}
}
// views
// - master.jsx
// - homepage.jsx
// src
// - index.js <-- We are here
const viewRoot = require('path').join(__dirname, '../views')
// Apply middleware
app.use(reactRenderware(viewRoot))
// Example route
app.use(async ctx => {
const messages = await db.latestMessages()
await ctx.render('homepage', {
messages
})
})
const React = require('react')
module.exports = ({ children, title, ctx }) => (
<html>
<title>
{title ? `${title} - Example.com` : 'The Best Example - Example.com'}
</title>
<body>
{ctx.currUser && ctx.currUser.role === 'ADMIN' && (
<a href="/admin">Go to admin panel</a>
)}
{children}
</body>
</html>
)
const React = require('react')
const Message = ({id, uname, text}) => (
<li>
{uname} said: {text}
</li>
)
module.exports = ({messages}) => (
<div>
<h2>Welcome to my site</h2>
<h3>Guestbook</h3>
<ul>
{messages.map(message => <Message {...message} />)}
</ul>
</div>
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment