Angular - Elements



What is an Angular Element?

Angular elements are reusable components that have been transformed into custom elements (also called Web Components). Angular provides a simple and effective method to create Web components.

Web components are custom HTML elements available in native HTML specifications to extend the features/tags of the HTML document. It can be created through JavaScript and can be made available in the HTML document. JavaScript has special methods to create custom HTML elements.

Creating custom HTML elements using JavaScript is a lengthy process and developers need to understand the internal workings of custom HTML elements and the Shadow DOM concept. Angular simplifies the process by enabling the conversion of Angular components to web components with minimal change in the component class.

Creating Angular Elements

Creating Angular elements means transforming a component into a custom element. For this purpose, the @angular/elements package is used. This package exports a createCustomElement() function that converts a component into a class that can be registered with the browser as a custom element.

Example

Let us learn how to create a custom HTML element in Angular.

In this example, we will create a component to display employee information (say EmpCard) and convert it into custom HTML element.

Step 1: Create an angular application, emp-card-web-component using Angular CLI.

ng new emp-card-web-component

Step 2: Create the emp-card component using Angular CLI.

ng generate component emp-card
CREATE src/app/emp-card/emp-card.component.html (24 bytes)
CREATE src/app/emp-card/emp-card.component.spec.ts (623 bytes)
CREATE src/app/emp-card/emp-card.component.ts (253 bytes)
CREATE src/app/emp-card/emp-card.component.css (0 bytes)

Step 3: Add encapsulation option in the @Component decorator with ViewEncapsulation.ShadowDom option. ShadowDom option enables the HTML native ShadowDom concept to preserve the styles of the component without leaking into the other part of the HTML document.

@Component({
   // ...
   encapsulation: ViewEncapsulation.ShadowDom
})
export class EmpCardComponent {
   // ...
}

Step 4: Next, add two input properties, name and role of the employee in the HTML element.

export class EmpCardComponent {
   @Input() name: string = '';
   @Input() role: string = '';
}

Step 5: The complete listing of the component is as follows −

import { Component, Input, ViewEncapsulation } from '@angular/core';

@Component({
   selector: 'app-emp-card',
   templateUrl: './emp-card.component.html',
   styleUrls: ['./emp-card.component.css'],
   standalone: true,
   encapsulation: ViewEncapsulation.ShadowDom
})
export class EmpCardComponent {
   @Input() name: string = '';
   @Input() role: string = '';
}

Step 6: Next, open the components template and add markup to display employee name and role as shown below −

<div class="card">
   <div class="container">
      <h4><b>{{ name }}</b></h4>
      <p>{{ role }}</p>
   </div>
</div>

Step 7: Next, open the components style and add css to show shadow in the employee card.

.card {
   box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
}

.card:hover {
   box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}

.container {
   padding: 2px 16px;
   max-width: 200px;
}

Step 8: Next, install @angular/elements module provided by angular team. @angular/elements module has options to create custom HTML element from angular component.

ng add @angular/elements
✔ Determining Package Manager
   Using package manager: npm
✔ Searching for compatible package version
   Found compatible package version: @angular/[email protected].
✔ Loading package information from registry
✔ Confirming installation
✔ Installing package
Package "@angular/elements" was found but does not support schematics.

Step 9: Next, open the main.ts file and remove all boilerplate code.

Step 10: Next, import createApplication from @angular/platform-browser. createApplication will bootstrap the angular application.

import { createApplication } from '@angular/platform-browser';

Step 11: Next, import createCustomElement from @angular/element module. createCustomElement will be used to create custom HTML element from the angular component.

import { createCustomElement } from '@angular/elements';

Step 12: Next, import EmpCardComponnet component as shown below −

import { EmpCardComponent } from './app/emp-card/emp-card.component'

Step 13: Next, create application using createAppliation() method by inputting providers and a callback method. The callback method will be used to create the custom HTML element from angular component.

createApplication({ providers: [] }).then((appRef) => {
   // ...
});

Step 14: Implement the callback method and create custom element using createCustomElement() method. createCustomElement accepts the component to be converted and the apps injector.

We can get injector from application reference returned from createApplication() method.

createApplication({ providers: [] }).then((appRef) => {
   const empCard = createCustomElement(
      EmpCardComponent,
      { injector: appRef.injector }
   );
});

Step 15: Next, register the created custom component using JavaScript native method, customElements.define() method.

createApplication({ providers: [] }).then((appRef) => {
   const empCard = createCustomElement(
      EmpCardComponent,
      { injector: appRef.injector }
   );
   
   customElements.define('emp-card', empCard);
});

Step 16: The complete listing of the main file, main.ts is as follows,

import { AppModule } from './app/app.module';

import { createApplication } from '@angular/platform-browser';
import { createCustomElement } from '@angular/elements';
import { EmpCardComponent } from './app/emp-card/emp-card.component'


createApplication({ providers: [] }).then((appRef) => {
   const empCard = createCustomElement(
      EmpCardComponent,
      { injector: appRef.injector }
   );
   
   customElements.define('emp-card', empCard);
});

Step 17: Next, buid the application using angular CLIs build command

ng build --configuration=production
Initial chunk files   | Names         |  Raw size | Estimated transfer size
main-5LWF45YA.js      | main          | 106.50 kB |                31.17 kB
polyfills-FFHMD2TL.js | polyfills     |  34.52 kB |                11.28 kB
styles-5INURTSO.css   | styles        |   0 bytes |                 0 bytes

                      | Initial total | 141.02 kB |                42.45 kB

Application bundle generation complete. [7.641 seconds]

Output location: D:\Angular\emp-card-web-component\dist\emp-card-web-component

Step 18: Once, the build is done, the output files are available in dist/emp-card-web-component folder. It has below files (similar files) along with a index.html file.

  • main-5LWF45YA.js
  • polyfills-FFHMD2TL.js
  • styles-5INURTSO.css

Step 19: Update the index.html file of the src folder with the newly created component and check the output for correctness.

<!doctype html>
<html lang="en">
<head>
   <meta charset="utf-8">
   <title>EmpCardWebComponent</title>
   <base href="/">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
   <emp-card name="John" role="Angular developer"></emp-card>
   <emp-card name="Maria" role="Frontend developer"></emp-card>
</body>
</html>

Here, we have added to emp-card tag with two different employee details.

Step 20: Finally, run the application and check the output in the browser.

Employee Information

Summary

As we learned, creating a web component is super easy in Angular. We just need to develop the component as normal angular component. Once the functionality of the component is developed, we need to add some bootstrapping code in the main.ts file and build the application to get the necessary custom HTML element as a bunch of native JavaScript. We can use it on any website without angular.

Advertisements