How to create a Web Component with StencilJS and Integrate it with Angular 2+

This 2 part guide is going to walk through the easiest way to create a simple web component with Stencil and integrate it with your Angular application.

Stencil Project Configuration:

  1. Let’s start with the most important part — creating a component in Stencil. To create a component, I recommend using the Stencil Component Starter project. Clone this repo into your local and follow the readme inside the github repo, which should lead to you seeing a screen similar to:
Initial Stencil Component Display

2. Now that you have a simple Stencil component component running in your local, it’s time to customize the component to make it your own. As a starter component, I made a very simple stylized button component — and here is the code in the my-component.tsx and my-component.css file to setup the button:

Couple of Notes:

  • You must include a componentWillLoad() and componentDidLoad() method in your tsx file, this will be needed to seamlessly integrate with Angular in the future. Without these methods, the rest of this tutorial will not work for you
  • For more details on the Prop decorator and the componentDidLoad methods, please visit the Stencil Docs

3. With your component code configured, you will be able to go ahead and view your component in your stencil project — to view the component, add the following html to your index.html file and add the following code in the body:

<torq-button buttontext="Button" buttontype="primary"></torq-button>

4. At this point, you should see your newly created component in your localhost:

Simple Button Component

5. Your last configuration change you need is to come up with a unique package name in your package.json for your component. After you have named your component, run the ‘npm run-script build’ command in your stencil project so that your dist folder for your component is created and ready to be published to npm.

6. At this point, you will need to publish your component to npm so that you can pull it down later in your Angular project. To do this, simply go to your root directory in your component stencil project and type ‘npm publish’. Note: if you have never published to npm before, you will need to create an account on www.npmjs.com first and run a ‘npm add user’ command inside in your workspace.


Angular Project Configuration:

  1. With your component published to NPM, you are now ready to import the component into your Angular project. I recommend using the angular-cli and the Angular starter app for the easiest setup. To make a new Angular app using the Angular cli, navigate to the directory where you want to create your app and run the commands seen on the home page of the angular cli website
  2. Next, as you might have guessed, it’s time to import the component you made in Stencil into your newly created angular app. To do this, in your terminal run ‘npm install <your-component-name>’
  3. Now that the component has been downloaded to your project, it’s time to integrate it with your Angular project. The steps to do this can be found on the Stencil website but I have copied them here and added some comments for clarity:

Including the Custom Elements Schema

Including the CUSTOM_ELEMENTS_SCHEMA in the module allows the use of the web components in the HTML markup without the compiler producing errors. Here is an example of adding it to AppModule:

This part can be copy pasted verbatim into your project:

import { BrowserModule } from '@angular/platform-browser';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { SharedModule } from './shared/shared.module';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, FormsModule, SharedModule],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}

Calling defineCustomElements

A component collection built with Stencil includes a main function that is used to load the components in the collection. That function is called defineCustomElements() and it needs to be called once during the bootstrapping of your application. One convenient place to do this is in main.ts as such:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { defineCustomElements } from '<your-component-name>/dist/loader';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
defineCustomElements(window);

You can ignore the 3rd step in the Stencil Angular configuration site as it is not needed and I will show you an easier setup below

4. The only other files you need to edit are the app.component.ts — in this file you will need to add an import statement for your component at the top of the file before the @Component decorator. The import statement will be written as import ‘<your-component-name>’. There is no need to change anything else in this file.

5. Now, you can come to your app.component.html file and call your component as a new html tag. For example, to call the simple button created earlier, all you need to write is:

<torq-button buttontext=”Button” buttontype=”primary”></torq-button>

6. Run ng-serve and you should see your stencil component in your AngularCLI project!

Hope this helps! Feel free to leave a comment if you see any errors or have any followup questions.