Angular Elements
Relevant source files
- adev/src/content/ecosystem/rxjs-interop/output-interop.md
- adev/src/content/examples/elements/src/app/app.ts
- adev/src/content/examples/elements/src/app/popup.service.ts
- adev/src/content/examples/elements/src/app/popup.ts
- adev/src/content/examples/elements/src/main.ts
- adev/src/content/guide/BUILD.bazel
- adev/src/content/guide/aria/BUILD.bazel
- adev/src/content/guide/components/host-elements.md
- adev/src/content/guide/components/inputs.md
- adev/src/content/guide/components/outputs.md
- adev/src/content/guide/components/programmatic-rendering.md
- adev/src/content/guide/components/queries.md
- adev/src/content/guide/components/selectors.md
- adev/src/content/guide/components/styling.md
- adev/src/content/guide/elements.md
- adev/src/content/guide/signals/effect.md
- adev/src/content/guide/signals/overview.md
- packages/animations/package.json
- packages/common/package.json
- packages/compiler-cli/package.json
- packages/compiler/package.json
- packages/core/package.json
- packages/core/src/di/host_attribute_token.ts
- packages/core/src/metadata/directives.ts
- packages/core/src/render3/reactivity/asserts.ts
- packages/elements/package.json
- packages/forms/package.json
- packages/language-service/package.json
- packages/localize/package.json
- packages/platform-browser-dynamic/package.json
- packages/platform-browser/package.json
- packages/platform-server/package.json
- packages/router/src/router_config_loader.ts
- packages/router/src/router_preloader.ts
- packages/router/src/url_handling_strategy.ts
- packages/router/test/standalone.spec.ts
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 allows Angular components to be consumed in non-Angular applications, server-rendered pages, or any context where standard HTML elements are used.
For information about creating standard Angular components, see Core Runtime Architecture. For server-side rendering, see Server-Side Rendering. For general security considerations when building web components, see Content Security and Sanitization.
Purpose and Architecture
Angular Elements bridges Angular's component model with the Web Components standard by transforming Angular components into browser-native custom elements. The transformation wraps Angular's dependency injection, change detection, and rendering infrastructure into a custom element that can be instantiated using standard DOM APIs.
Architecture Overview
Sources: adev/src/content/guide/elements.md1-169
Package Structure and Core APIs
The @angular/elements package exports several key types and functions for creating and managing custom elements.
Core Package Exports
Key Functions and Types:
Sources: adev/src/content/guide/elements.md36-62 adev/src/content/guide/elements.md104-162 packages/elements/package.json1-40
Component Transformation Process
The transformation from an Angular component to a custom element follows a specific process that involves metadata extraction, constructor creation, and registration with the browser.
Transformation Pipeline
Implementation Steps:
- Component Analysis: The
createCustomElement()function inspects the component's metadata to identify input properties and output events. packages/core/src/metadata/directives.ts181-190 - Attribute Mapping: Input property names are transformed to dash-separated lowercase attribute names. Property aliases (from
@Input({alias: 'name'})) are respected. adev/src/content/guide/components/inputs.md175-186 - Event Mapping: Output properties become Custom Events with the output name (or alias) as the event type. adev/src/content/guide/components/outputs.md1-50
- Constructor Generation: An
NgElementConstructoris created that implements the custom element lifecycle callbacks. - Registration: The generated constructor is registered with the browser using
customElements.define().
Sources: adev/src/content/guide/elements.md49-78 packages/core/src/metadata/directives.ts181-190 adev/src/content/guide/components/inputs.md175-186
Property and Event Mapping
Angular Elements automatically maps component properties and events to Web Components standards.
Input Property Mapping
Output Event Mapping
Naming Conventions:
| Component Feature | Custom Element Equivalent | Example |
|---|---|---|
@Input() prop | prop attribute (dash-case) | inputValue → input-value |
@Input({alias: 'x'}) prop | x attribute (dash-case) | myProp → my-prop |
@Output() event | CustomEvent with type name | valueChanged → valueChanged event |
@Output({alias: 'x'}) event | CustomEvent with alias | myClick → myClick event |
Sources: adev/src/content/guide/elements.md63-78 adev/src/content/guide/components/inputs.md175-195
Lifecycle and Bootstrapping
Custom elements created with Angular Elements manage their own lifecycle and automatically bootstrap Angular's runtime infrastructure when attached to the DOM.
Custom Element Lifecycle
Self-Bootstrapping Behavior:
Custom elements created with Angular Elements are self-bootstrapping:
- They start automatically when added to the DOM (
connectedCallback). - They destroy themselves when removed from the DOM (
disconnectedCallback). - No Angular-specific initialization is required by the host application.
- Each custom element instance maintains its own Angular component instance via
ComponentRef. adev/src/content/guide/components/programmatic-rendering.md185-193
Sources: adev/src/content/guide/elements.md14-18 adev/src/content/guide/components/programmatic-rendering.md185-193
Example: Popup Service Implementation
The Angular documentation includes a complete example demonstrating both traditional dynamic component loading and the custom elements approach.
Popup Service Architecture
Key Implementation Differences:
The traditional dynamic component loading approach (adev/src/content/examples/elements/src/app/popup.service.ts18-42):
- Requires explicit
createComponent()call. - Must manually attach to
ApplicationRef. - Needs to wire up component properties manually.
- Requires explicit cleanup on destruction.
The custom element approach (adev/src/content/examples/elements/src/app/popup.service.ts44-59):
- Uses standard DOM API
document.createElement(). - Properties set directly on the element.
- Events handled with standard
addEventListener(). - Automatic cleanup when removed from DOM.
Type Safety with Custom Elements:
Sources: adev/src/content/examples/elements/src/app/popup.service.ts1-61 adev/src/content/guide/elements.md79-102
Type System Integration
Angular Elements provides TypeScript types to enable type-safe interactions with custom elements.
Type Augmentation Pattern:
The WithProperties and NgElement types allow TypeScript to understand custom element properties:
Type Hierarchy:
| Type | Extends | Purpose |
|---|---|---|
NgElement | HTMLElement | Base interface for Angular-created custom elements |
WithProperties<T> | NgElement | Adds component-specific properties to NgElement |
HTMLElementTagNameMap | Native interface | Browser's type mapping for element tag names |
When HTMLElementTagNameMap is augmented, TypeScript automatically provides correct types for:
document.createElement('my-dialog')returns the correct type.document.querySelector('my-dialog')returns the correct type.- Property access is type-checked.
- IDE autocomplete works for component properties.
Sources: adev/src/content/guide/elements.md104-162
Registration and Usage Pattern
Bootstrap Configuration:
Important Considerations:
The component's selector should not be used as the custom element tag name. Using the same name can cause Angular to create two component instances for a single DOM element:
- One regular Angular component (from the selector match). adev/src/content/guide/components/selectors.md1-50
- One custom element wrapper (from the custom element definition).
Sources: adev/src/content/guide/elements.md59-62 adev/src/content/guide/elements.md86-102 adev/src/content/guide/components/selectors.md1-50
Limitations and Known Issues
Angular Elements has specific limitations related to the browser's custom element lifecycle:
Known Issues:
| Issue | Description | Affected Scenarios |
|---|---|---|
disconnect() callback | Problems with custom element disconnect behavior | Destroying and re-attaching elements |
| AngularJS integration | Issues when rendering in ng-if or ng-repeat | Hybrid AngularJS/Angular applications |
| Manual DOM manipulation | Detaching and re-attaching can cause issues | Dynamic DOM operations |
Recommended Practices:
- Avoid destroying and re-attaching custom elements when possible.
- If dynamic visibility is needed, use CSS
displayorvisibilityproperties instead of removing from DOM. - Test thoroughly when integrating with AngularJS or other frameworks that manipulate the DOM.
- Be aware that the custom element lifecycle is controlled by the browser, not Angular.
Sources: adev/src/content/guide/elements.md163-169
Integration with Angular Ecosystem
Dependencies on Core Angular Systems:
Angular Elements relies on several core Angular systems:
Security Considerations:
Custom elements inherit Angular's security model:
- Template bindings are sanitized automatically.
- Content Security Policy applies to inline styles.
- XSS protection applies to dynamic content.
For detailed security considerations, see Content Security and Sanitization.
Sources: adev/src/content/guide/elements.md1-169 packages/core/package.json1-55 packages/compiler-cli/package.json1-31
Refresh this wiki
On this page
- Angular Elements
- Purpose and Architecture
- Package Structure and Core APIs
- Component Transformation Process
- Property and Event Mapping
- Lifecycle and Bootstrapping
- Example: Popup Service Implementation
- Type System Integration
- Registration and Usage Pattern
- Limitations and Known Issues
- Integration with Angular Ecosystem
