Reputation: 701
I was trying to find the right way to implement SEO in your Meteor app, but can't find any good examples. I feel like what I'm doing is working, but to some extent and could be way better. This is what I'm doing for SEO in my Meteor app:
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Language" content="en-us" />
<meta name="google" value="notranslate" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="google-site-verification" content="google-verification-id" />
<meta name="msvalidate.01" content="bing-verification-id" />
</head>
SeoCollection = new Mongo.Collection('SeoCollection');
Meteor.startup(function() {
if (Meteor.isClient) {
return SEO.config({
title: ’title',
meta: {
'description': ’siteDescription',
'keywords': ‘keyword, keyword, keyword',
'charset': 'utf-8',
'site_name': ’siteName',
'url':'http://siteName.com',
'viewport': 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no',
'X-UA-Compatible': 'IE=edge,chrome=1',
'HandheldFriendly': 'true',
'apple-mobile-web-app-capable' : 'yes',
'apple-mobile-web-app-status-bar-style': 'black',
'referrer': 'never',
},
og: {
'title': ’siteTitle',
'description': ’siteDescription',
'image': 'image.png',
'type': 'website',
'locale': 'en_us',
'site_name': 'siteName',
'url': 'http://sitename.com'
},
rel_author: 'https://plus.google.com/+appPage/'
});
}
SeoCollection.update(
{
route_name: 'homepage'
},
{
$set: {
route_name: 'homepage',
title: ’title',
meta: {
'description': ’siteDescription',
'keywords': ‘keyword, keyword, keyword',
'charset': 'utf-8',
'site_name': ’siteName',
'url':'http://siteName.com',
'viewport': 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no',
'X-UA-Compatible': 'IE=edge,chrome=1',
'HandheldFriendly': 'true',
'apple-mobile-web-app-capable' : 'yes',
'apple-mobile-web-app-status-bar-style': 'black',
'referrer': 'never',
},
og: {
'title': ’siteTitle',
'description': ’siteDescription',
'image': 'image.png',
'type': 'website',
'locale': 'en_us',
'site_name': 'siteName',
'url': 'http://sitename.com'
},
rel_author: 'https://plus.google.com/+appPage/'
}
},
{
upsert: true
}
);
});
and dynamically using Iron:router -
this.route('page:data', {
path: '/page',
onBeforeAction: function() {
SEO.set({
title: data.title,
meta: {
'description': 'description',
},
og: {
'title': data.title,
'description': 'description',
'image': data.image
}
})
this.next();
}
})
sitemaps.add('/items.xml', function() {
var out = [], pages = Collection.find().fetch();
_.each(pages, function(page) {
out.push({
page: 'page/' + page.encodedUrl,
lastmod: page.date,
});
});
return out;
});
Problems I encounter:
Spiderable package works only in Google. It's true that it has the largest market share, but this way for 30% of SEO traffic from other search engines it works really bad.
I'm not sure if I should have all that stuff in seo.js file also in head tag. I know seo.js overwrites it, but when I request title from url on Reddit, it says no title tag find. It might be similar with other search engines from my perspective. But then there'd be multiple same tags, that is not good either.
What I'm doing good or wrong?
Upvotes: 1
Views: 1352
Reputation: 6584
You might want to consider FlowRouter SSR, which uses server-side rendering for HTTP requests. It generates the entire DOM on the server, and sends it as an initial static HTML <body>
, thereby enabling all web spiders to crawl your site, not just Google. After that, your app will just continue to function as a real-time webapp, overriding the initial DOM.
It also supports subscriptions, thus you can use Mongo collections to render crawable content, too. But unfortunately it only works with React for now.
Upvotes: 1
Reputation: 11376
The best way to handle this (atleast on my case), was using prerender.io + manuelschoebel:ms-seo in this way.
How?
Installing prerender, here you can use.
meteor add dfischer:prerenderio
NOTE If you get
res.send(status, body): Use res.status(status).send(body) instead
You will have to use the npm package itself.
Now Meta Tags.
for this you can create a function like this.
setSEO = function(seoData){
SEO.set({
title: seoData.title,
meta: {
'description': seoData.description
},
og: {
'title': seoData.title,
'description': seoData.description,
'image':seoData.image,
'fb:app_id':seoData.appId
}
});
};
And then just call it on the onAfterAction
hook
Router.map(function() {
self.route('route.name', {
path: '/some',
template: 'test',
name: 'route.name',
onAfterAction: function() {
setSEO(pageData.seoData);
}
});
});
And thats it, on my side its working on twitter, g+, facebook, linkedin, pinterest.
Upvotes: 3