ostrio:iron-router-meta

v1.1.0Published 6 years ago

This package has not had recent updates. Please investigate it's current state before committing to using it in your project.

Reactive meta tags, Scripts and CSSs for Meteor and Iron-Router

Change meta tags on the fly within iron-router. This package can create meta tags, and link/script tags as well.

This package may also help to use dynamic CSSs and JSs, so you may use different style sheets - for different routes.

This package supports meta, script and link options (properties) defined on objects below, ordered by prioritization:

  • Router.route() [overrides all]
  • RouteController.extend()
  • Router.configure() [might be overridden by any above]

Note: this package implies ostrio:iron-router-title package.

Install:

meteor add ostrio:iron-router-meta

Demo application:

ToC:

Usage:

Change CSS and JS per route:

1// Set default CSS and JS for all routes
2Router.configure({
3  link: {
4    twbs: {
5      href: 'https://maxcdn.bootstrapcdn.com/bootstrap/2.3.2/css/bootstrap.min.css',
6      rel: 'stylesheet'
7    }
8  },
9  script: {
10    twbs: "https://maxcdn.bootstrapcdn.com/bootstrap/2.3.2/js/bootstrap.min.js"
11  }
12});
13
14// Rewrite default CSS, for second route, via controller:
15var secondPageController = RouteController.extend({
16  link: {
17    twbs: {
18      href: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css',
19      rel: 'stylesheet'
20    }
21  },
22  script: {
23    twbs: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"
24  }
25});
26
27Router.route('secondPage', {
28  controller: secondPageController
29});
30
31// Rewrite default CSS, for third route via route settings:
32Router.route('thirdPage', {
33  link: {
34    twbs: {
35      href: 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha/css/bootstrap.min.css',
36      rel: 'stylesheet'
37    }
38  },
39  script: {
40    twbs: "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha/js/bootstrap.min.js"
41  }
42});

Set default tags:

1Router.configure({
2  meta: {
3    charset: {
4      charset: 'UTF-8'
5    },
6    keywords: {
7      name: 'keywords',
8      itemprop: 'keywords',
9      content: 'Awesome, Meteor, based, app'
10    },
11    robots: 'index, follow',
12    google: 'notranslate'
13  },
14  link: {
15    canonical: function() {
16      return window.location.href;
17    },
18    image: {
19      rel: 'image',
20      sizes: '500x500',
21      href: 'http://doma..'
22    },
23    publisher: 'http://plus.google...',
24    twbs: {
25      href: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css',
26      rel: 'stylesheet'
27    }
28  },
29  script: {
30    twbs: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js',
31    base64: {
32      src: 'https://cdnjs.cloudflare.com/ajax/libs/Base64/0.3.0/base64.min.js',
33      async: true,
34      defer: true
35    }
36  }
37});

Set on route level

1Router.route('account', {
2  template: 'account',
3  path: '/me/account',
4  title: 'My Account',
5  meta: {
6    keywords: {
7      name: 'keywords',
8      itemprop: 'keywords',
9      content: 'User, Account'
10    }
11  }
12});

Set via RouteController:

1var accountController = RouteController.extend({
2  meta: {
3    keywords: 'User, Account'
4  }
5});
6
7Router.route('account', {
8  controller: accountController
9});

Other examples:

Set only name and content attributes on meta tag:

1Router.route('routeName', {
2  meta: {
3    name: 'content'
4  }
5});

Set only rel and href attributes on link tag:

1Router.route('routeName', {
2  link: {
3    rel: 'href'
4  }
5});

Set multiple attributes on meta tag:

1Router.route('routeName', {
2  meta: {
3    uniqueName: {
4      name: 'name',
5      content: 'content',
6      value: 'value',
7      'og:prop': 'value',
8      itemprop: 'value'
9    }
10  }
11});

Set multiple attributes on link tag:

1Router.route('routeName', {
2  link: {
3    uniqueName: {
4      rel: 'name',
5      sizes: 'value',
6      href: 'value',
7      type: 'value'
8    }
9  }
10});

Use function(s) as value:

1Router.route('routeName', {
2  meta: {
3    url: {
4      property: 'og:url',
5      itemprop: 'url',
6      content: function() {
7        return window.location.href;
8      }
9    }
10  },
11  link: {
12    canonical: function() {
13      return window.location.href;
14    }
15  }
16});

Use function context:

1Router.route('post', {
2  template: 'post',
3  path: '/post/:_id',
4  meta: function() {
5    return {
6      keywords: {
7        name: 'keywords',
8        itemprop: 'keywords',
9        content: function() {
10          return this.data.getKeywords();
11        }
12      }
13    };
14  },
15  data: {
16    getKeywords: function() {
17      return PostsCollection.findOne(this.params._id).keywords;
18    }
19  }
20});

Bootstrap configuration

1Router.configure({
2  meta: {
3    charset: {
4      charset: 'UTF-8'
5    },
6    keywords: {
7      name: 'keywords',
8      itemprop: 'keywords',
9      content: 'Awesome, Meteor, based, app'
10    },
11    description: {
12      name: 'description',
13      itemprop: 'description',
14      property: 'og:description',
15      content: 'Default description'
16    },
17    image: {
18      name: 'twitter:image',
19      itemprop: 'image',
20      property: 'og:image',
21      content: 'http://doma..'
22    },
23    'og:type': 'website',
24    'og:title': function() {
25      return document.title;
26    },
27    'og:site_name': 'My Awesome Site',
28    url: {
29      property: 'og:url',
30      itemprop: 'url',
31      content: function() {
32        return window.location.href;
33      }
34    },
35    'twitter:card': 'summary',
36    'twitter:title': function() {
37      return document.title;
38    },
39    'twitter:description': 'Default description',
40    'twitter:site': {
41      name: 'twitter:site',
42      value: '@twitterAccountName'
43    },
44    'twitter:creator': {
45      name: 'twitter:creator',
46      value: '@twitterAccountName'
47    },
48    'http-equiv': {
49      'http-equiv': 'X-UA-Compatible',
50      content: 'IE=edge,chrome=1'
51    },
52    robots: 'index, follow',
53    google: 'notranslate'
54  },
55  script: {
56    twbs: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"
57  },
58  link: {
59    twbs: {
60      href: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css',
61      rel: 'stylesheet'
62    },
63    canonical: function() {
64      return window.location.href;
65    },
66    image: {
67      rel: 'image',
68      sizes: '500x500',
69      href: 'http://doma..'
70    },
71    publisher: 'http://plus.google...',
72    'shortcut icon': {
73      rel: 'shortcut icon',
74      type: 'image/x-icon',
75      href: 'http://domai...'
76    },
77    'icon': {
78      rel: 'icon',
79      type: 'image/png',
80      href: 'http://domai...'
81    },
82    'apple-touch-icon-144': {
83      rel: 'apple-touch-icon',
84      sizes: '144x144',
85      href: 'http://doma..'
86    },
87    'apple-touch-icon-114': {
88      rel: 'apple-touch-icon',
89      sizes: '114x114',
90      href: 'http://doma..'
91    },
92    'apple-touch-icon-72': {
93      rel: 'apple-touch-icon',
94      sizes: '72x72',
95      href: 'http://doma..'
96    },
97    'apple-touch-icon-57': {
98      rel: 'apple-touch-icon',
99      sizes: '57x57',
100      href: 'http://doma..'
101    }
102  },
103});