Angular Dynamic meta tags in head

2019-01-28 07:23发布

I need to insert open graph meta tags on a particular page in an angular app.

These tags are different based on the news or video that the page has.

I tried adding a variable to the $rootscope. This variable will be populated with the meta tags when it is relevant.

Now here is my issue. As soon as this variable gets populated with the HTML string, they don't form a part of the head and are instead outputted to the body. I have searched for a day and could not find any viable solutions. Any help would be appreciated

4条回答
Animai°情兽
2楼-- · 2019-01-28 07:57

If you are using ui-router, you can use $stateChangeSuccess to set dynamically meta description and other meta tags based on current state. You have to put custom meta description in each state defined in $stateProvider.state(...).

You must have <meta name="description" content="Default Description"> in HTML markup, then and then document.getElementsByTagName('meta') will be able to return the meta description tag.

$stateProvider
    .state('app.about', {
        url: 'about',
        templateUrl: '/modules/core/client/views/about.client.view.html',
        controller: 'AboutController',
        controllerAs: 'vm',
        metaDesc: 'Learn about my awesome social site.',
        data: {
            pageTitle: 'About | The Social Site'
        }
    })

$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {

    var metaDesc = $state.current.metaDesc || "Default Meta Description";

    var metas = document.getElementsByTagName('meta');

    for (let i = 0; i < metas.length; i++) {
        if (metas[i].getAttribute("name") === "description") {
            metas[i].setAttribute("content", metaDesc);
            break;
        }
    }
});
查看更多
萌系小妹纸
3楼-- · 2019-01-28 08:04

I want to re-answer this question. Infact, all your need a directive. You should set all your meta values as an object such as : {name:'keywords',content:'angularjs, directive,meta'}

If you want to add it on $rootScope it can be like this :

$rootScope.metas = [{
  name:'description',
  content :'AngularJS meta example'
},{
  name:'keywords',
  content :'AngularJS, metas, example'
},{
  charset:'UTF-8'
}];

Then you can use object's keys as an attribute and theirs value. Repeat the directive and pass all your metas in it. If you dont want a clear html you can create an empty meta element in javascript and add attributes on it. Then replace the directive element's outerHTML with your the new meta element's outerHTML. You can check this page : Simple Dynamic Meta Tags in AngularJS

查看更多
Lonely孤独者°
4楼-- · 2019-01-28 08:05

I created an Angular module that can be used to set meta tags dynamically using the $routeProvider route definitions.

angular.module('YourApp','ngMeta')
.config(function ($routeProvider, ngMetaProvider) {

  $routeProvider
  .when('/home', {
    templateUrl: 'home-template.html',
    meta: {
      //Sets 'Home Page' as the title when /home is open
      title: 'Home page', 
      description: 'This is the description of the home page!'
    }
  })
  .when('/login', {
    templateUrl: 'login-template.html',
    meta: {
      //Sets 'Login Page' as the title when /login is open
      title: 'Login page',
      description: 'Login to this wonderful website!'
    }
  })
});

You can then set the meta tags in HTML like so

<title ng-bind="ngMeta.title"></title>
<!-- OR <title>{{ngMeta.title}}</title> -->    

<!-- This meta tag can be set using ngMetaProvider -->
<meta property="og:type" content="{{ngMeta.ogType}}" />

<!-- Default locale is en_US -->
<meta property="og:locale" content="{{ngMeta.ogLocale}}" />

<!-- This meta tag changes based on the meta object of each route -->
<!-- or when the setDescription function is called -->
<meta name="description" content="{{ngMeta.description}}" />

To set the title, description and og:image dynamically, you can inject ngMeta into your controller

.controller('DemoCtrl', function(ngMeta) {

    ngMeta.setTitle('Demo page');
    ngMeta.setDescription('This is the description of the demo page');
    ngMeta.setOgImgUrl('http://example.com/abc.jpg');
});

Support for more tags and ui-router are in the works.

查看更多
迷人小祖宗
5楼-- · 2019-01-28 08:17

I was having a similar problem with Apple's Smart App Banner. You may be able to apply a similar logic if you are still looking for an answer.

<html ng-app="myNewsApp">`
<head>
  <title> myNews </title>
  <meta property="og:url" content={{opengraph.urlArgument()}}/>
</head>

I set up a service that populates the urlArgument with the id as per this answer., and used it in the page controller.

module.controller('myNewsVideoCtrl', function($scope, $stateParams, $rootScope, openGraph ){
  $rootScope.opengraph = openGraph;
  $rootScope.opengraph.set("http://www.imdb.com/title/"+$stateParams.videoID);
})
查看更多
登录 后发表回答