Has anyone of you already figured out an elegant way on how to deal with meta tags with AngularJS in SPA mode?
In a base template I have some default meta tags. For each route, each controller is loading a different view with different contents. Very normal. But how can I alter the meta tags for each of these pages?
Furthermore some pages should have more meta tags, others less. For example pages with contents should have additional meta tags for social media sharing. Other sensitive pages should have the no-follow meta tags to forbid robots indexing the page.
Curious how the experienced are coping with this?
In our Angular application, we will add a Meta tag and page title by using the Meta service. We will use @angular/platform-browser to get the Title and Meta service. Here, we will explain many functions such as addTag(), getTag(), updateTag(), and removeTag(). We can also use these functions to manipulate Meta tags.
Metadata tagging is the process of creating a term that describes a keyword or phrase and assigning those tags to a media asset. A media asset, as described in our blog about digital asset management, is any content that comes in one of five forms —audio, images, video, documents, or HTML.
The <meta> tag defines metadata about an HTML document. Metadata is data (information) about data. <meta> tags always go inside the <head> element, and are typically used to specify character set, page description, keywords, author of the document, and viewport settings.
A pattern I have used comes from the ngBoilerplate project. In this pattern, there is an overall app controller which deals with a "global" scope, including meta tags.
You individual pages' controllers could emit an event when they are navigated to, $locationChangeSuccess
if you are using the default router.
The app controller listens for this event, and uses it to update the page title in the case of ngBoilerplate: https://github.com/ngbp/ngbp/blob/v0.3.2-release/src/app/app.js#L17-L21
However, there's nothing to stop you from emitting an object with whatever meta tag info you like, then having a listener for that event.
// on your individual app pages goes something like this
function SomePageController($scope) {
// the event gets fired when the page is loaded and the controller is called.
$scope.$emit('newPageLoaded', { 'title': 'Some Page', 'description': 'blah' });
}
// your overall app controller
function AppController($scope) {
$scope.metadata = {
'title': 'default title',
'description': 'default description',
};
// whenever a controller emits the newPageLoaded event, we update the app's metadata
$scope.$on('newPageLoaded', function(event, metadata) {
$scope.metadata = metadata
});
}
Then in your header you could do something like this:
<html ng-app="myApp" ng-controller="AppController">
<head>
<meta title="{{ metadata.title }}" ng-if="metadata.title" />
<meta description="{{ metadata.description}}" ng-if="metadata.description" />
<meta whatever="{{ metadata.whatever}}" ng-if="metadata.whatever" />
</head>
I've not tested this code, so there may be errors, but I think the general principle is sound.
In your question you mention the use-case of incorporating tags for social media sharing. I assume you mean something like open graph or twitter etc.
In this case it is important to know that currently the crawlers that these sites (facebook ,twitter, pinterest etc) use will not execute your JavaScript and will thus not be able to read any meta tags that you dynamically populate with Angularjs.
I have written a blog post about this issue, with a suggested solution: http://www.michaelbromley.co.uk/blog/171/enable-rich-social-sharing-in-your-angularjs-app/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With