Created
March 10, 2016 23:00
-
-
Save tonyxiao/92e3d994eec0d762a17e to your computer and use it in GitHub Desktop.
Inject custom dochead into html returned by meteor server. Credit goes to https://github.com/thereactivestack/meteor-react-router-ssr
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
import React from 'react' | |
import {IndexRoute, Route} from 'react-router' | |
import Helmet from 'react-helmet' | |
const wrap = (Component) => (location, cb) => { | |
cb(null, Component) | |
} | |
const makeHelmet = (info) => { | |
const {title, description, image, url} = { | |
title: 'Your site title', | |
description: 'Your site description', | |
image: 'https://drscdn.500px.org/photo/100057305/q%3D80_m%3D2000/ac293a79b0845e8f4df02eba256077ce', | |
url: 'https://google.com', | |
...info | |
} | |
return <Helmet | |
title={title} | |
meta={[ | |
{property: 'og:url', content: url}, | |
{property: 'og:title', content: title}, | |
{property: 'og:type', content: 'website'}, | |
{property: 'og:description', content: description}, | |
{property: 'og:image', content: image}, | |
{name: 'description', content: description} | |
]} /> | |
} | |
export default function ({Collections}) { | |
return ( | |
<Route path='/'> | |
<IndexRoute component={() => makeHelmet()} /> | |
<Route path='tonyx' component={() => makeHelmet({title: 'Tony Xiao'})} /> | |
<Route path='topics/:topicId' getComponent={wrap(({params}) => { | |
const topicId = Collections.Topics.findOne(params.topicId) | |
return topicId ? makeHelmet({ | |
title: topicId.displayName, | |
url: topicId.cover && channel.cover.url, | |
description: topicId.description | |
}) : <noscript /> | |
})} /> | |
<Route path='*' component={() => makeHelmet()} /> | |
</Route> | |
) | |
} |
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
import {Meteor} from 'meteor/meteor' | |
import {WebApp} from 'meteor/webapp' | |
import {RoutePolicy} from 'meteor/routepolicy' | |
import React from 'react' | |
import ReactDOMServer from 'react-dom/server' | |
import {match, RouterContext} from 'react-router' | |
import Helmet from 'react-helmet' | |
// meteor algorithm to check if this is a meteor serving http request or not | |
const IsAppUrl = (url) => { | |
if (url === '/favicon.ico' || url === '/robots.txt') { | |
return false | |
} | |
// NOTE: app.manifest is not a web standard like favicon.ico and | |
// robots.txt. It is a file name we have chosen to use for HTML5 | |
// appcache URLs. It is included here to prevent using an appcache | |
// then removing it from poisoning an app permanently. Eventually, | |
// once we have server side routing, this won't be needed as | |
// unknown URLs with return a 404 automatically. | |
if (url === '/app.manifest') { | |
return false | |
} | |
// Avoid serving app HTML for declared routes such as /sockjs/. | |
if (RoutePolicy.classify(url)) { | |
return false | |
} | |
return true | |
} | |
const patchResWrite = (originalWrite, head) => { | |
return function (data) { | |
if (typeof data === 'string' && data.indexOf('<!DOCTYPE html>') === 0) { | |
// Add react-helmet stuff in the header (yay SEO!) | |
data = data.replace('<head>', | |
`<head>${head.title}${head.base}${head.meta}${head.link}${head.script}`) | |
// '<head>' + head.title + head.base + head.meta + head.link + head.script | |
} | |
originalWrite.call(this, data) | |
} | |
} | |
export default Meteor.bindEnvironment((routes) => { | |
console.log('Will inject dochead handler into Meteor') | |
WebApp.connectHandlers.use(Meteor.bindEnvironment((req, res, next) => { | |
if (!IsAppUrl(req.url)) { | |
return next() | |
} | |
match({routes, location: req.url}, Meteor.bindEnvironment((err, redirectLocation, renderProps) => { | |
if (!err && !redirectLocation && renderProps) { | |
console.log('Will patch res.write with dochead info url =', req.url) | |
ReactDOMServer.renderToStaticMarkup(React.createElement(RouterContext, renderProps)) | |
const head = Helmet.rewind() | |
res.write = patchResWrite(res.write, head) | |
} | |
next() | |
})) | |
})) | |
}) |
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
import context from './configs/context' | |
import initDocheadRoutes from './dochead/docheadRoutes.jsx' | |
import injectDochead from './dochead/injectDochead' | |
injectDochead(initDocheadRoutes(context)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment