Comparison
Maybe another library fits your needs. Or setting metadata values yourself is better than adding a third party dependency (who wants to maintain yet another dependency? 😜)
So here's a comparison of some libraries found in NPM JS at moment of writing this document1
TL;DR
Poor maintenance
One of the main motifs of creating this library was not finding any maintained enough library. Check the maintenance section for more details.
Something which frustrated me was finding peer dependencies fixed to an older version of Angular (see the versions support in maintenance section). That forces you to use npm
's --legacy-peer-deps
every time you npm install
for instance. Or emits a warning in other package managers.
Also, the code was not being updated since long time ago. Meta elements are not something that change often, but at least one would expect dependencies to be updated from time to time.
Poor extensibility
Libraries allow you to set other <meta>
tags from the support ones. But you have to clear them manually when route changes. So it's half the job IMO. Also, you can't set other things that aren't <meta>
elements. What if you want to set some <script>
like in JSON-LD case? Or change the lang
attribute?
Non-standard metas
Some libraries set metadata elements that are redundant. Or even wrong (they do not exist, or it is not the appropriate form to communicate something). Checkout the notes at the end of the by specific metadata elements section for more information.
Do it yourself
It is certainly a better option than installing a poorly maintained library. But you'll lack bundle size optimizations we've cooked here. And maybe you'll miss setting the metadata in a declarative manner as route's data. Or the helper types to help you recall all available metadata of a standard like Open Graph or Twitter Cards.
Candidates
Candidate | Analyzed version | Latest version | License |
---|---|---|---|
@avivharuzi/ngx-seo |
v16.0.0 | ||
@ngaox/seo |
v5.0.0 | ||
@ngx-meta/core |
v9.0.0 |
By maintenance
Maintenance | 🙋 ngx-meta |
@avivharuzi/ngx-seo |
@ngaox/seo |
@ngx-meta/core |
---|---|---|---|---|
versions support | v15-v186 | v13-16 | v15 | v9 |
Documentation | ✅ | ✅ | ✅ | ✅ |
Last commit | ||||
Unit tests | ||||
E2E tests | ❌ | ❌ | ❌ | |
Code coverage | ❌ | |||
Provenance | ||||
Collaborators |
By features
Feature | 🙋 ngx-meta |
No lib | @avivharuzi/ngx-seo |
@ngaox/seo |
@ngx-meta/core |
---|---|---|---|---|---|
SSR support | ✅ | ⚙️ | ✅ | ✅ | ✅ |
Hydration support | ✅ | ⚙️ | ✅ | ✅ | ✅ |
Metadata with service | ✅ | ⚙️ | ✅ | ✅ | ✅ |
Metadata in route | ✅ | ⚙️❗️ | ✅ | ✅ | ✅8 |
Metadata with component | ❌ | ⚙️❗️ | ❌ | ✅ | ❌ |
Default metadata values | ✅ | ⚙️ | ❌ | ✅ | ✅ |
Extensible | ✅ | ✅ | |||
Change metadata on route change | ✅ | ⚙️ | ✅ | ✅ | ✅ |
Bundle size optimizations | ✅ | ⚙️❗️ | ❌ | ❌ | ❌ |
Tree-shakeable | ✅ | ⚙️ | ❌ | ❌ | ❌ |
Shared metadata3 | ✅ | ⚙️ | ✅ | ✅ | ✅ |
Specific, non-shared metadata4 | ✅ | ⚙️ | ⚙️10 | ⚙️10 | ⚙️10 |
Legend
Icon | Meaning |
---|---|
✅ | Supported |
Partially supported | |
⚙️ | Can be done quite straight forward |
⚙️❗️ | Can be done but will require some work |
❌ | Not possible in analysed version |
By common metadata groups
Built-in setters | 🙋 ngx-meta |
@avivharuzi/ngx-seo |
@ngaox/seo |
@ngx-meta/core |
---|---|---|---|---|
Standard metas5 | ✅ | ✅ | ✅ | ✅ |
Open Graph metas | ✅ | ✅ | ✅ | ✅ |
Twitter Cards metas | ✅ | ✅ | ❌ | |
JSON LD script | ✅ | ❌ | ❌ | ❌ |
You can set manually in your app any
<meta>
element without any library. For instance, using Angular'sMeta
APIs yourself (actually, that's what most libs use under the hood)
Legend
Icon | Meaning |
---|---|
✅ | Provided built-in |
Partially provided built-in | |
❌ | Not provided built-in (may be set as custom ones if library allows to) |
By specific metadata elements
Metadata element | 🙋 ngx-meta |
@avivharuzi/ngx-seo |
@ngaox/seo |
@ngx-meta/core |
---|---|---|---|---|
<title> |
✅ | ✅ | ✅ | ✅ |
<meta name="description"> |
✅ | ✅ | ✅ | ✅ |
<meta name="author"> |
✅ | ✅ | ⚙️ | ✅ |
<meta name="keywords"> |
✅ | ✅ | ✅ | ✅ |
<meta name="generator"> |
✅ | ⚙️ | ⚙️ | ⚙️ |
<meta name="application-name"> |
✅ | ⚙️ | ⚙️ | ⚙️ |
<meta name="theme-color"> |
✅ | ⚙️ | ⚙️ | ⚙️ |
<link rel="canonical"> |
✅ | ❌ | ✅ | ❌ |
<html lang> |
✅ | ❌ | ❌ | ❌ |
<meta property="og:title"> |
✅ | ✅ | ✅ | ✅ |
<meta property="og:type"> |
✅ | ✅ | ✅ | ⚙️ |
<meta property="og:image"> |
✅ | ✅ | ✅ | ⚙️ |
<meta property="og:image:secure_url"> |
✅ | ⚙️ | ✅7 | ⚙️ |
<meta property="og:image:alt"> |
✅ | ⚙️ | ✅ | ⚙️ |
<meta property="og:image:height"> |
✅ | ⚙️ | ✅ | ⚙️ |
<meta property="og:image:width"> |
✅ | ⚙️ | ✅ | ⚙️ |
<meta property="og:image:type"> |
✅ | ⚙️ | ✅ | ⚙️ |
<meta property="og:url"> |
✅ | ✅ | ✅ | ✅ |
<meta property="og:description"> |
✅ | ✅ | ✅ | ✅ |
<meta property="og:site_name"> |
✅ | ✅ | ✅ | ⚙️ |
<meta property="og:locale"> |
✅ | ⚙️ | ⚙️ | ✅ |
<meta property="og:profile:first_name"> |
✅ | ⚙️ | ⚙️ | ⚙️ |
<meta property="og:profile:last_name"> |
✅ | ⚙️ | ⚙️ | ⚙️ |
<meta property="og:profile:username"> |
✅ | ⚙️ | ⚙️ | ⚙️ |
<meta property="og:profile:gender"> |
✅ | ⚙️ | ⚙️ | ⚙️ |
<meta name="twitter:card"> |
✅ | ✅ | ✅ | ⚙️ |
<meta name="twitter:title"> |
✅ | ✅ | ✅ | ⚙️ |
<meta name="twitter:description"> |
✅ | ✅ | ✅ | ⚙️ |
<meta name="twitter:site"> |
✅ | ⚙️ | ✅ | ⚙️ |
<meta name="twitter:site:id"> |
✅ | ⚙️ | ⚙️ | ⚙️ |
<meta name="twitter:creator"> |
✅ | ⚙️ | ✅ | ⚙️ |
<meta name="twitter:creator:id"> |
✅ | ⚙️ | ⚙️ | ⚙️ |
<meta name="twitter:image"> |
✅ | ✅ | ✅ | ⚙️ |
<meta name="twitter:image:alt"> |
✅ | ⚙️ | ✅ | ⚙️ |
<script type="application/ld+json"> |
✅ | ❌ | ❌ | ❌ |
<meta property="fb:app_id"> |
⚙️ | ⚙️ | ✅ | ❌ |
Legend
Icon | Meaning |
---|---|
✅ | Provided built-in |
⚙️ | Can be set as custom meta (library allows to) |
❌ | Can't be set with library |
Some elements were purposely skipped from the comparison
<meta itemprop="name">
,<meta itemprop="description">
and<meta itemprop="image">
are supported by@avivharuzi/ngx-seo
. But those are redundant. Name and description can be specified by<title>
and namesake's<meta name="description">
. The image can be set using Open Graph and most platforms will read it + also set the social cards / link previews at same time.<meta name="title">
is supported by@ngaox/seo
. But you probably don't need it, it's a metadata element not specified in any standard
Some libraries set invalid metadata elements
<meta name="canonical">
is set by@avivharuzi/ngx-seo
. However, that metadata name is not standard.<link rel="canonical">
is the HTML spec standard way of specifying canonical URLs.<meta name="twitter:url">
is set by@avivharuzi/ngx-seo
. However, that metadata name is not specified in Twitter Cards markup reference<meta name="twitter:image:alt">
is set by@ngaox/seo
withproperty
attribute instead ofname
attribute. A PR has been opened to fix it<meta property="og:author">
and<meta property="og:publisher">
are supported by@ngx-meta/core
. But those are not valid Open Graph elements. In any case, they would be<meta property="og:article:author|publisher">
Excluded candidates
Some libraries were excluded from analysis for following reasons
angular-update-meta
- Not in scope. Only supports AngularJS
-
Keywords used to find libraries:
angular meta
,angular meta tags
,ngx meta
. Tried sorting by different criteria: relevance / popularity / maintenance. Excluded libraries for AngularJS ↩ -
Doesn't appear in docs. However, you can set extra Angular
MetaDefinition
s, but they won't be cleared when changing route. Unless you manually do so. ↩ -
You can set a metadata value that will be used for several purposes. Like a title for
<title>
and Open Graph's<meta property="og:title">
↩ -
You can specify a specific metadata value that will be used for only one purpose, whilst the shared metadata value is used for the rest. Like a specific value for
<title>
and another for Open Graph's<meta property="og:title">
↩ -
In HTML spec. Mainly
<title>
and some<meta>
s likedescription
,author
,keywords
↩ -
You can't manage it yourself. Library sets it if URL starts with
https
↩ -
Requires declaring a guard (
MetaGuard
) in every route with metadata. ↩ -
You can set custom
<meta>
tags programmatically using service. But only in the shape of<meta name='{key}' content='{value}'>
. You then have to manually clear it when changing route. Not available via the route's data. ↩ -
You can set extra Angular
MetaDefinition
s, but they won't be cleared when changing route. Unless you manually do so. ↩