Angular module for providing MetaTags support based on routes.

Usage no npm install needed!

<script type="module">
  import tfMetatags from '';



Codeship Status for thiagofesta/tf-metatags Build Status TravisCI npm Code Climate

Angular module for providing MetaTags support based on routes.

Inspired from angular-metatags and used some ideas from ui-router-metatags.


When using ui-router 1 or higher, use tf-metatags 2 or higher.

ui-router tf-metatags
>= 1.0.0 >= 2.0.0
< 1.0.0 < 2.0.0.


Download tf-metatags.min.js and include it on your page

<script src="tf-metatags.min.js"></script>

Include it in your module declaration

angular.module('myApp', ['ui.router', 'tf.metatags']);

Add the tfMetaTags service to your page

<title ng-bind="tfMetaTags.title"></title>
<meta ng-repeat="(key, value) in" name="{{key}}" content="{{value}}" >

Then configure defaults

  .config(['tfMetaTagsProvider', function (tfMetaTagsProvider) {

      title: 'Default Title',
      properties: {
        keywords: 'keyword1, keyword2'

    tfMetaTagsProvider.setTitleSuffix(' | MetaTags');
    tfMetaTagsProvider.setTitlePrefix('Prefix ');


And finally decorate the routes with tfMetaTags:

  .config(['$stateProvider', function ($stateProvider, $windowProvider) {

    var $window = $windowProvider.$get();

      .state('home', {
        url: '/',
        tfMetaTags: {
          title: 'Home',
          properties: {
            description: 'This is the homepage',
            keywords: 'keyword1, keyword2',
            'og:title': 'Home',
            'og:url': function() {
              return $window.location.href;
            'twitter:title': 'Home'
      .state('movie', {
        url: '/movie',
        resolve: {
          /* @ngInject */
          movieData: function($q, $timeout) {
            var deferred = $q.defer();
            $timeout(function() {
                title: 'The Lord of the Rings: The Fellowship of the Ring',
                year: 2001,
                summary: 'A meek hobbit of the Shire and eight companions set out on a journey to Mount Doom to destroy the One Ring and the dark lord Sauron.'
            }, 1000);
            return deferred.promise;
        tfMetaTags: {
          /* @ngInject */
          title: function(movieData) {
            return movieData.title;
          properties: {
            description: 'Summary: {{movieData.summary}}; Year: {{movieData.year}}'


SEO concerns

Until the search engine bots will be able to execute javascript properly you will have to use a tool like or brombone to serve prerendered pages when a bot visit your site.

You can read more for the topic on the following articles: - Angular & SEO finally a piece of cake - The Basics of JavaScript Framework SEO in AngularJS - AngularJS and SEO

Running sample app & Testing

First you need to install the dependencies

npm install
./node_modules/bower/bin/bower install && ./node_modules/protractor/bin/webdriver-manager update

Now you are able to have the server up and running. Go and start the server

grunt server

Running tests

We have JSHint, JSCS, Unit tests and E2E tests.

All of them can be run once using the following command

grunt test

You can see the coverage on the command line output or more details opening the test/coverage/index.html file on your browser.

Running JSHint

For running JSHint

grunt test:jshint
Running JSCS

For running JSCS

grunt test:jscs
Running Unit Tests

For running unit tests

grunt test:unit
Running E2E Tests

For running E2E

grunt test:e2e


For create a build run

grunt build

This task will also make sure all tests are passing before making the build, once build is completed it also perform tests against the generated code.