Angular Elements provides the capability to package Angular components as custom elements (web components) that can be used in any HTML document, regardless of the framework. This facilitates using Angular components in non-Angular applications, server-rendered pages, or any context where standard HTML elements are consumed.
Angular Elements bridges Angular's component model with the Web Components standard by transforming Angular components into native browser custom elements. This transformation wraps Angular's dependency injection, change detection, and rendering infrastructure into a custom element, which can be instantiated via standard DOM APIs.
This layered architecture shows how an Angular component's metadata and template feed into the createCustomElement() API in the @angular/elements package, producing an NgElementConstructor. This constructor extends HTMLElement and is registered with the browser's customElements registry. The created custom element integrates Angular's change detection and event mappings while exposing attribute/property bindings according to web standards.
Sources: adev/src/content/guide/elements.md1-13 adev/src/content/guide/elements.md36-48
The process from Angular component to custom element involves analyzing component metadata, generating a custom element constructor, and registering it with the browser.
Component Analysis
The createCustomElement() function introspects the Angular component's metadata to locate input properties and output events, essential for mapping to attributes and DOM events adev/src/content/guide/elements.md68-70
Attribute Mapping
Input properties are mapped to custom element attributes by converting camelCase property names to dash-case attribute names (e.g., inputProp → input-prop) adev/src/content/guide/elements.md70-71
Event Mapping
Component outputs annotated with @Output() are transformed into DOM CustomEvent instances. Emitted values are stored in the event’s detail property to conform with Web Component event patterns adev/src/content/guide/elements.md73-75
Constructor Generation
An NgElementConstructor class is generated extending HTMLElement, encapsulating Angular component bootstrapping, change detection, and lifecycle management inside the element’s DOM callbacks (connectedCallback and disconnectedCallback) adev/src/content/guide/elements.md53-54
Registration
The created constructor is registered as a custom element using customElements.define(), enabling instantiation via standard HTML tags or DOM APIs adev/src/content/guide/elements.md56-58
Sources: adev/src/content/guide/elements.md49-78 packages/core/src/metadata/directives.ts181-190
Angular Elements automatically maps Angular inputs and outputs to the respective custom element attributes and events.
| Component Feature | Custom Element Equivalent | Mapping Rule |
|---|---|---|
@Input() inputProp | input-prop attribute | Dash-separated lowercase attribute |
@Output() valueChanged | valueChanged custom event | Dispatched as CustomEvent with payload in detail |
| Output Aliases | Aliased event name | Event name respects output aliases |
This mapping allows seamless two-way binding of data and events between Angular components and custom elements in any environment.
Sources: adev/src/content/guide/elements.md63-78 packages/core/src/metadata/directives.ts181-190
Custom elements created through Angular Elements handle their lifecycle natively in the browser and bootstrap Angular's runtime when inserted into the DOM.
Creation: The browser constructs the element instance when its tag is parsed or created via DOM APIs adev/src/content/guide/elements.md45-46
Bootstrap: On insertion into the DOM (connectedCallback), the component bootstraps its Angular context including change detection and rendering adev/src/content/guide/elements.md16
Destruction: Upon removal (disconnectedCallback), the Angular component instance is properly destroyed to free resources adev/src/content/guide/elements.md16
This autonomous lifecycle management ensures custom elements can operate independently and integrate well in any HTML environment.
Sources: adev/src/content/guide/elements.md14-18 adev/src/content/guide/elements.md45-48
Angular's runtime includes support for rendering "foreign components" such as custom elements, integrating them into Angular's rendering tree.
ɵɵforeignComponent
This is a creation phase instruction that renders a foreign component by creating an anchor node and hosting an LContainer which manages the embedded view packages/core/src/render3/instructions/foreign_component.ts48-81
createForeignView
Responsible for instantiating a specialized embedded view for the foreign component within the hosting container packages/core/src/render3/instructions/foreign_component.ts84
ɵɵforeignContent
Handles the rendering of child nodes of a foreign component by extracting the root DOM nodes and arranging them for projection into the foreign view packages/core/src/render3/instructions/foreign_component.ts159-168
This infrastructure allows Angular to integrate elements created outside of the Angular framework within its rendering and change detection system.
Sources: packages/core/src/render3/instructions/foreign_component.ts48-110 packages/core/src/render3/instructions/foreign_component.ts159-182
A concrete example demonstrates how a PopupComponent is packaged and registered as a custom element.
The Angular PopupComponent is transformed via the createCustomElement() API in the @angular/elements package adev/src/content/examples/elements/src/app/app.ts26
The resulting PopupElement constructor is then registered as a custom element using the browser's native customElements.define() function adev/src/content/examples/elements/src/app/app.ts26
Once registered, standard DOM APIs such as document.createElement('popup-element') can be used to instantiate the popup element, independent of Angular context adev/src/content/examples/elements/src/app/popup.service.ts44-59
Sources: adev/src/content/guide/elements.md79-102 adev/src/content/examples/elements/src/app/popup.service.ts44-59
Tag Naming
Avoid using the component’s original selector as the custom element tag name. Doing so can cause Angular to instantiate the component twice on the same DOM node, once as an Angular component and once as a custom element. Use distinct tag names to prevent this conflict adev/src/content/guide/elements.md59-62
Framework Agnostic
Once registered, the custom element behaves as a standard HTML element without any Angular-specific runtime dependencies or knowledge required on the consumer side. This enables framework-agnostic integration adev/src/content/guide/elements.md14-18
Sources: adev/src/content/guide/elements.md59-62 adev/src/content/guide/elements.md14-18
Refresh this wiki
This wiki was recently refreshed. Please wait 4 days to refresh again.