[SOLVED] SSR using picker and flow-router


#1

Continuing the discussion from Facebook share setup:

I’m using Flow-Router with Meteor 1.5.1. Based on the topic above, I’ve tried to create the following SSR route using meteorhacks:ssr and meteorhacks:picker

I disabled my flow-router route for /blog/:post_id and implemented the following server-side route. I get a 404 error (the default flow-router route) whenever I try to navigate to a /blog/post_id route.

Any help is appreciated.

/private/layout.html

{{{getDocType}}}
<html lang="en">
  <head>
      <meta name="description" content="description"/>
     {{> Template.dynamic template=template data=data}}
  </head>
</html>

/server/seo/layout.js

SSR.compileTemplate('seoLayout', Assets.getText('layout.html'));
Template.seoLayout.helpers({
  getDocType: function() {
    return "<!DOCTYPE html>";
  }
});

/private/blogpost.html

<title>Post : {{post.title}}</title>
<!-- Open Graph Meta Tags -->
<meta property="og:type" content="website"/>
<meta property="og:title" content="{{post.title}}"/>
<meta property="og:description" content="{{post.subtitle}}"/>
<meta property="og:site_name" content="Sid Kwakkel's Blog"/>
<meta property="og:url" content="https://sidkwakkel.com/blog/{{post.id}}"/>
<meta property="og:image" content=""/>
<!-- just testing this getting in here -->
<!-- Twitter Card Meta Tags -->
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="{{post.title}}"/>
<meta name="twitter:description" content="{{post.subtitle}}"/>
<meta name="twitter:image" content=""/>
<meta name="twitter:site" content="@SidKwakkel"/>
<meta name="twitter:creator" content="@SidKwakkel"/>

/server/seo/blogpost.js

SSR.compileTemplate('blogpost', Assets.getText('blogpost.html'));
Template.blogpost.helpers({})

/server/serverroutes.js

var seoPicker = Picker.filter(function(req, res) {
  var isCrawler = [];
  var string = req.headers['user-agent'];
  isCrawler.push(/_escaped_fragment_/.test(req.url));
  if(string){
      isCrawler.push(string.indexOf('facebookexternalhit') >= 0);
      isCrawler.push(string.indexOf('Slack') >= 0);
      isCrawler.push(string.indexOf('Twitterbot') >= 0);
  }
  return isCrawler.indexOf(true) >= 0;
});

seoPicker.route('/blog/:postid', function(params, req, res){
    var post = Posts.findOne({_id:params.postid});
    var html = SSR.render('seoLayout',{
        template:'blogpost',
        data: {post:post}
    });
    res.end(html);
});

Blog app for Business, Corporate and IT professionals: SidKwakkel.com
#2

Actually, this works as prescribed. I re-enabled the flow-router route, so now users get the reactive version. When I have Google render the page in Google Search Console, it renders the complete HTML (NIce!)

Looks like we’re good here!


#4

Hi! I’m trying to use the same example to get Twitter and Facebook to find my metatags, it works for Facebook/OpenGraph, but for some reason doesn’t work for Twitter. Have you tried the Twitter Card validator (https://cards-dev.twitter.com/validator) with your page? Curious to know if it works for you or not :).


#5

I got this to work by setting the response header in the route instead of trying to set it with HTML meta tags, so extending the example like this:

seoPicker.route('/blog/:postid', function(params, req, res){
    var post = Posts.findOne({_id:params.postid});
    var html = SSR.render('seoLayout',{
        template:'blogpost',
        data: {post:post}
    });
    res.setHeader( 'Content-Type', 'text/html; charset=utf-8' );
    res.end(html);
});

#6

Quite right @gustavlrssn. the setHeader line improves my Google+ and Twitter uptake. Nicely done.


#7

How can we test it in localhost ?

I’m using meteor 1.7.0.4