Inject head data when using flow-router ssr for seo purpose

Hi, I’m trying to build something with flow router and to leverage server side rendering. Since I use react, I removed the blaze html package and I need to inject some meta tags in the head. Here’s how I proceed :

/**
 * Listen to every messages recieved
 */
WebApp.connectHandlers.use( function ( req, res, next ) {

	/* If the requested url is not a web page, stops here */
	if ( /\/favicon/.test( req.url ) || req.url === '/robots.txt' || req.url === '/app.manifest' || !/html/.test( req.headers.accept ) )
		return next();

	/* The tags to inject, starts with the basic elements */
	let injection = `<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>`;

	res.dataToInject = injection;

	return next();

} );

/**
 * Overwrite the basic write method
 */
let originalWrite = http.OutgoingMessage.prototype.write;
http.OutgoingMessage.prototype.write = function ( chunk, encoding ) {

	/* If this is a buffer, convert it to string */
	if ( this.dataToInject ) {
		chunk = chunk.toString().replace( '<head>', '<head>' + this.dataToInject );
	}
	originalWrite.call( this, chunk, encoding );
};

Basically, I just check that the request is for a page and I inject some html.

This would be a great place to inject some tags like title, and some meta like description, facebook open graph and stuff like that.

With req.url, I get can the url. But how do I break it down into the route name and parametters ? I could go with a regex, but there has to be something in FlowRouter to do that, no ?

And maybe this is not the best way to add seo data in my pages. Anyone has a better idea ?

Have you tried the static-html package? It parses .html files and just adds static body and head content, without doing the template stuff that blaze-html-templates does.

Hi. It could replace my solution for the viewport meta tag injection problem. But this is static, not dynamic.

The question is : for a specific route, how do I inject dynamically a title ?

(and an open graph meta tag and …)

Yeah; right now there isn’t any way to do that except for the super duper hacks above. Unless someone else has an idea. @zoltan - do you have any thoughts on this?

You need this: https://github.com/kadirahq/meteor-dochead

Haha, why am I even bothering to code ! I sould just explore your repository :smile:

I works flawlessly, thank you.

Two small things :

  • Client side, DocHead.setTitle( 'Drafts management' ); works everywhere. Server side, it works in the render() method, but not in componentDidMount() as said in the documentation. But it also works in the action method when defining a route, and this is nicer (will it stay that way ?), you could mention it.
  • You never append just one meta, a dozen seems like a reasonable number. It would be awesome if addMeta could accept an array of objects.

Thanks again for you work !

1 Like

Yeah! You should :smile:

  • It works on the render() method and it’ll work it like that way in the future as well.
  • May be do this: [{}, {}].forEach(meta => DocHead.addMeta(meta))

Yup, it works in the render, as said in the readme. But it also works in the action methods. And it makes way more sense to me :

FlowRouter.route( '/', {

	name: 'Home',

	action( params, queryParams ) {

		DocHead.setTitle( 'My page title' );..

__
Yes, I did that (with an underscore each).