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:
- Source
Live: http://iron-router-meta.meteor.com(We are looking for free hosting for this demo)
ToC:
- Change CSS and JS per route
- Set default tags
- Set on route level
- Set via RouteController
- Other examples
- Use function(s) as value
- Use function's context
- Bootstrap configuration
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});