Skip to content

<meta> element APIs

TL;DR

APIs to manage <meta> elements on the page changed to improve development experience. NgxMetaMetaService and related APIs are deprecated in favour of NgxMetaElementsService and related APIs

See migration for more info about how to migrate.

Summary

Key Value
Category of change 👎 Deprecation
Automatic migration schematics No
Introduced in version 1.0.0-beta.24

Description

Issue

🎟️ GitHub PR with details

APIs to manage <meta> elements on the page had several issues:

  • Unneeded abstraction: NgxMetaMetaService requires as first argument an NgxMetaMetaDefinition and then the content to place in there. Idea behind that definition type was to model and manage a kind of <meta> elements. Like <meta name="description"> for instance. But this can be done without introducing an additional type / abstraction. Which adds unnecessary cognitive load to do something simple as managing <meta> elements.
  • Limited abstraction: NgxMetaMetaDescription has two properties:
  • attrSelector: identifies the kind of <meta> elements. Like name="description". So they can be created, updated or removed depending on the metadata to set on the page. Nothing wrong with it.
  • withContent: a function that given some content as string, generates an Angular's MetaDefinition. This was done so that Open Graph metadata name is placed in a property attribute. Though most names are placed in a name attribute. Or to customize the attribute holding the content if needed. However, sometimes more attributes are needed for a <meta> element. A string is then not enough to specify them all. Like theme color standard meta.
  • Coupled API design: NgxMetaMetaService second argument is the content to set to the <meta> element. That content is a string because of NgxMetaMetaDefinition.withContent. It couples even more to the abstraction above. And also it inherits the limitation of being a string.
  • Can't set multiple <meta> elements. If calling the API to set a given <meta>, it will replace existing element. Can't add more than one. This is an issue for metadata that may need multiple <meta> elements. Like theme color standard meta or Open Graph arrays

  • Too long names: I know, subjective. But NgxMetaMetaDefinition feels too long. Same for makeKeyValMetaDefinition and makeComposedKeyValMetaDefinition

Solution

As APIs are coupled, introducing a compatibility layer on top of existing ones would:

  • Add more complexity to existing ones to manage both old and new usages.
  • Increase bundle size because of this extra compatibility layer

So newer APIs were designed to solve the existing issues. The goals of these new APIs are then:

  • No unneeded abstractions: everything should be able to be specified without introducing extra abstractions. Using primitive types. Helper functions can be introduced as syntactic sugar.

  • Support <meta> elements with more attributes: not just name and content ones. For instance theme color standard meta can specify the media attribute.

  • Support setting multiple <meta> elements

  • Shorter names

Changes

Following set of APIs are deprecated1:

And the following set of APIs are introduced:

See GitHub PR were they were introduced more details. Keep reading for how to migrate from old ones to newer ones.

Migration

Automatic

No automatic migration via schematics are available for this change. Manual migration is required

Manual

Here you have some examples of how the same thing can be achieved using old and new APIs:

Set a single <meta> element

Let's set a <meta name="description"> element:

Before
const metaService = inject(NgxMetaMetaService)
metaService.set(
  makeKeyValMetaDefinition('description'), 
  'foo'
)
After
const metaService = inject(NgxMetaElementsService)
metaService.set(
  withNameAttribute('description'), 
  withContentAttribute('foo')
)

Remove all <meta> elements of a kind

Let's remove all <meta name="description"> elements:

Before
const metaService = inject(NgxMetaMetaService)
metaService.set(
  makeKeyValMetaDefinition('description'),
  undefined, // or null
)
After
const metaService = inject(NgxMetaElementsService)
metaService.set(
  withNameAttribute('description'),
  undefined, // or null or empty array
)
// or also just
metaService.set(
  withNameAttribute('description'), 
  withContentAttribute(undefined)
)

Set <meta> element with more attributes

Like a <meta name="theme-color"> with a media attribute:

Before
const metaService = inject(NgxMetaMetaService)
metaService.set(
  makeKeyValMetaDefinition(
    'theme-color', 
    { extras: { media: '(prefers-color-scheme: dark)' } }
  ), 
  'darkblue'
)
After
const metaService = inject(NgxMetaElementsService)
metaService.set(
  withNameAttribute('theme-color'), 
  withContentAttribute(
    'darkblue',
    { media: '(prefers-color-scheme: dark)' }
  )
)

Set many <meta> elements

Like multiple <meta name="theme-color">:

Before
// ❌ Not possible with library-provided APIs
After
const metaService = inject(NgxMetaElementsService)
metaService.set(
  withNameAttribute('theme-color'), 
  [
    withContentAttribute(
      'darkblue', 
      { media: '(prefers-color-scheme: dark)' }
    ),
    withContentAttribute('lightblue')
  ]
)

For a detailed explanation of new APIs, visit its API reference

Notices

It's recommended to upgrade to new APIs to reduce bundle size. As internally, new APIs are used. So if you consume the deprecated APIs in your project, you're adding two API sets to the bundle that achieve the same purpose.

Deprecated references

If you still need to see information about deprecated APIs, check out:


  1. For more details, check out the deprecation PR