以正确的方式对 Meteor 应用实施 SEO

Implement SEO to Meteor app the right way

我试图找到在您的 Meteor 应用程序中实施 SEO 的正确方法,但找不到任何好的示例。我觉得我正在做的事情很有效,但在某种程度上可能会更好。这就是我在 Meteor app:

中为 SEO 所做的工作
  1. 我使用的包:spiderable,gadicohen:sitemaps,manuelschoebel:ms-seo
  2. 头标签:

<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>

  1. 这就是我使用 ms-seo package 所做的:在 seo.js 文件中:

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
        }
    );

});

并动态使用 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();
    }
  })

  1. 使用 gadicohen:sitemaps 提交站点地图:

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;
});

  1. 使用 meteor-up to deploy the app, it installs phantomJS. It combined with spiderable 包启用 google 抓取您的应用程序。

我遇到的问题:

  1. Spiderable 包仅适用于 Google。它确实拥有最大的市场份额,但这种方式对于来自其他搜索引擎的 30% 的 SEO 流量来说效果非常糟糕。

  2. 我不确定我是否应该将 seo.js 文件中的所有内容也放在 head 标记中。我知道 seo.js 会覆盖它,但是当我在 Reddit 上向 url 请求标题时,它说找不到标题标签。从我的角度来看,它可能与其他搜索引擎相似。但是这样的话会有多个相同的标签,这也不好。

  3. 我做的好还是不好?

处理此问题的最佳方法(至少在我的情况下)是以这种方式使用 prerender.io + manuelschoebel:ms-seo。

如何?

正在安装prerender,这里可以使用

meteor add dfischer:prerenderio

注意 如果你得到

res.send(status, body): Use res.status(status).send(body) instead

您将不得不使用 npm 包本身。

现在元标签。

为此你可以创建一个这样的函数。

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
          }
        });
};

然后在 onAfterAction 钩子上调用它

 Router.map(function() {
  self.route('route.name', {
    path: '/some',
    template: 'test',
    name: 'route.name',
    onAfterAction: function() {
      setSEO(pageData.seoData);
    }
  });
});

就是这样,在我这边,它在推特、g+、facebook、linkedin、pinterest 上工作。

您可能需要考虑 FlowRouter SSR,它对 HTTP 请求使用服务器端呈现。它在服务器上生成整个 DOM,并将其作为初始静态 HTML <body> 发送,从而使所有网络蜘蛛能够抓取您的网站,而不仅仅是 Google。之后,您的应用程序将继续作为实时网络应用程序运行,覆盖初始 DOM.

它还支持订阅,因此您也可以使用 Mongo 集合来呈现可抓取的内容。但不幸的是,它目前只适用于 React。