![<ngx-meta/> for Angular](../docs/content/images/logo.png)

[![Angular](https://img.shields.io/badge/Works_with-Angular_v15--v21-f11653?logo=angular&logoColor=white&link=https%3A%2F%2Fangular.dev%2F)](https://angular.dev/)
[![Supports Angular SSR/Universal](https://custom-icon-badges.demolab.com/badge/Supports-Angular_SSR%2FUniversal-blue.svg?logo=angular-universal&link=https%3A%2F%2Fangular.dev%2Fguide%2Fssr)][SSR]

[![NPM Downloads](https://img.shields.io/npm/dt/%40davidlj95%2Fngx-meta?logo=npm&label=NPM%20downloads&link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2F%40davidlj95%2Fngx-meta)](https://www.npmjs.com/package/@davidlj95/ngx-meta)
[![NPM License](https://img.shields.io/npm/l/%40davidlj95%2Fngx-meta?logo=npm&label=License&link=https%3A%2F%2Fgithub.com%2Fdavidlj95%2Fngx%2Fblob%2Fmain%2Fprojects%2Fngx-meta%2Fsrc%2FLICENSE)](https://github.com/davidlj95/ngx/blob/main/projects/ngx-meta/src/LICENSE)
[![NPM Version](https://img.shields.io/npm/v/%40davidlj95%2Fngx-meta?logo=npm&label=Latest%20version&link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2F%40davidlj95%2Fngx-meta)](https://www.npmjs.com/package/@davidlj95/ngx-meta)
[![CI/CD workflow](https://github.com/davidlj95/ngx/actions/workflows/cicd.yml/badge.svg)](https://github.com/davidlj95/ngx/actions/workflows/cicd.yml)
[![Codecov](https://codecov.io/gh/davidlj95/ngx/graph/badge.svg)](https://codecov.io/gh/davidlj95/ngx)
[![GitHub last commit (branch)](https://img.shields.io/github/last-commit/davidlj95/ngx/main?logo=github&label=Last%20commit&link=https%3A%2F%2Fgithub.com%2Fdavidlj95%2Fngx%2Fcommits%2Fmain%2F)](https://github.com/davidlj95/ngx/commits/main/)

[![Coded in Typescript](https://img.shields.io/badge/Coded_in-TypeScript-007ACC?logo=typescript&logoColor=white&link=https%3A%2F%2Fwww.typescriptlang.org)](https://www.typescriptlang.org)
[![Git](https://img.shields.io/badge/VCS-Git-f05032?logo=git&logoColor=f05032&link=https%3A%2F%git-scm.com%2F)](https://git-scm.com/)
[![GitHub](https://img.shields.io/badge/Repository_hosted_in-GitHub-181717?logo=github&logoColor=181717&link=https%3A%2F%github.com%2F)](https://github.com/)
[![Package manager: pnpm](https://img.shields.io/badge/Package_manager-pnpm-f69220?logo=pnpm&link=https%3A%2F%2Fpnpm.io%2F)](https://pnpm.io/)
[![Unit tests with Jasmine](https://img.shields.io/badge/Unit_tests_with-Jasmine-8A4182?logo=Jasmine&logoColor=white&link=https%3A%2F%2Fjasmine.github.io)](https://jasmine.github.io)
[![Unit tests ran by Karma](https://custom-icon-badges.demolab.com/badge/Unit_tests_ran_by-Karma-42beae.svg?logo=karma-runner&link=https%3A%2F%2Fkarma-runner.github.io)](https://karma-runner.github.io)
[![E2E tests with Cypress](https://img.shields.io/badge/E2E_tests_with-Cypress-69D3A7?logo=cypress&link=https%3A%2F%2Fwww.cypress.io)](https://www.cypress.io)
[![Code coverage with Codecov](https://img.shields.io/badge/Code_coverage_with-Codecov-F01F7A?logo=codecov&logoColor=F01F7A&link=https%3A%2F%2F.codecov.io)](https://codecov.io)
[![Linted with ESLint](https://img.shields.io/badge/Linted_with-ESLint-3A33D1?logo=eslint&logoColor=white&link=https%3A%2F%2Feslint.org)](https://eslint.org)
[![Formatted with Prettier](https://img.shields.io/badge/Formatted_with-prettier-1A2C34?logo=prettier&logoColor=F7BA3E&link=https%3A%2F%2Fprettier.io)](https://prettier.io)
[![Commits follow Conventional Commits convention](https://img.shields.io/badge/Commits_convention-Conventional_Commits-FE5196?logo=conventionalcommits&logoColor=white&link=https%3A%2F%2Fconventionalcommits.org)](https://conventionalcommits.org)
[![Git hooks with Husky](https://img.shields.io/badge/Git_hooks_with-Husky%F0%9F%90%B6-1a1a1e?link=https%3A%2F%2Ftypicode.github.io%2Fhusky%2F)](https://typicode.github.io/husky/)
[![GitHub Actions](https://img.shields.io/badge/CI%2FCD%20with-GitHub_Actions-2088FF?logo=githubactions&logoColor=2088FF&link=https%3A%2F%github.com%2Ffeatures%2Factions)](https://github.com/features/actions)
[![Released with Semantic Release](https://img.shields.io/badge/Released_with-Semantic_Release-e10079?logo=semantic-release&link=https%3A%2F%2Fgithub.com%2Fsemantic-release%2Fsemantic-release)](https://github.com/semantic-release/semantic-release)
[![Dependencies updated with Renovate](https://img.shields.io/badge/Dependencies_updated_with-Renovate-1a1f6c?logo=renovate&link=https%3A%2F%2Frenovatebot.com)](https://renovatebot.com)
[![Docs with Material for Mkdocs](https://img.shields.io/badge/Docs_with-Material_for_Mkdocs-526CFE?logo=materialformkdocs&logoColor=white&link=https%3A%2F%2Fsquidfunk.github.io%2Fmkdocs-material%2F)](https://squidfunk.github.io/mkdocs-material/)
[![API Report/Docs with API Extractor](https://custom-icon-badges.demolab.com/badge/API_Report_&_Docs_with-API_Extractor-383938.svg?logo=api-extractor&link=https%3A%2F%2Fapi-extractor.com%2F)](https://api-extractor.com/)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/davidlj95/ngx/blob/main/CODE_OF_CONDUCT.md)

Set your Angular site's metadata: standard meta tags, Open Graph,
Twitter Cards, JSON-LD structured data and more.
Supports SSR (and Angular Universal).
Use a service. Use routes' data.
Set it up in a flash! 🚀

## Motivation

You have a nice Angular-powered website. You want to improve its SEO and decide to add some metadata in your pages. You also enable [Server Side Rendering (SSR)][SSR] so when search engines visit your site, metadata elements are already in the HTML returned by the server. You start adding nice `<meta name="description">` to describe your home page. Then Open Graph metadata like `<meta property="og:title">` [to customize social cards / link previews](https://www.freecodecamp.org/news/what-is-open-graph-and-how-can-i-use-it-for-my-website/). You use [Angular's `Meta` APIs][Angular Meta APIs] to insert those in your DOM. All good so far 😊

Now, you want to set metadata for another page of your site 🤔

Calls to [Angular `Meta` APIs][Angular Meta APIs] start appearing in many places around. Object literals specifying `<meta>` definitions breed like rabbits 🐇 You also have to ensure when changing pages that metadata from a page doesn't stay there when visiting another. It's all starting to be a bit tedious 😅

If only there was a way to easily specify metadata I want for each page in a declarative fashion and forget about it 🙏 You're in the right place then 🎉 This library will definitely help you 🥳

[SSR]: https://angular.dev/guide/ssr
[Angular Meta APIs]: https://angular.dev/api/platform-browser/Meta

## 🗺️ Start exploring

### New users

First, welcome 🥰

Wondering why this library and not another one? Take a look at [why section](https://ngx-meta.dev/why/). Probably, the most interesting parts are [**features**](https://ngx-meta.dev/why/features/) and [**comparison**](https://ngx-meta.dev/why/comparison/) pages.

For the hands-on devs ([_this is the way_](https://knowyourmeme.com/memes/this-is-the-way)), [**get started now** ⚡️](https://ngx-meta.dev/get-started/)

### Existing users

Take a look at guides to refresh your knowledge. Like the one about setting metadata programmatically [**using the service**](https://ngx-meta.dev/guides/set-metadata-using-service/), in a declarative fashion [**using route's data**](https://ngx-meta.dev/guides/set-metadata-using-routing/). Or how [**metadata values JSON**](https://ngx-meta.dev/guides/metadata-values-json/) is shaped.

Go deeper by:

- [**Setting default metadata**](https://ngx-meta.dev/guides/defaults/) values for all pages
- [**Setting up URL resolution**](https://ngx-meta.dev/guides/url-resolution/) to use relative URLs but get absolute URLs as metadata values
- [**Formatting page titles**](https://ngx-meta.dev/guides/title-formatting/) to apply a consistent format to all page titles
- [**Loading metadata later**](https://ngx-meta.dev/guides/late-loading-modules/) to reduce main bundle size
- [**Providing your custom metadata managers**](https://ngx-meta.dev/guides/manage-your-custom-metadata/)
- [**Fine-grained choosing metadata elements**](https://ngx-meta.dev/guides/custom-metadata-providers-selection/) you're interested in. Rest of them won't end up in your bundle

Are you by any chance looking for the [**API reference**](https://ngx-meta.dev/api/ngx-meta/)?

If you see some deprecations and want to fix them, take a look at the **migrations** section in the [docs site](https://ngx-meta.dev)
