Try LitElement

This documentation is a work in progress. It describes prerelease software, and is subject to change.

Try LitElement in live-editable code without installing anything. Build your first component, use it in a web page, and add style with CSS.

This tutorial has live code samples that you can edit, like this:

Click Preview at any time to see your code in action.

If you’re doing the tutorial in your local development environment, you’ll need to make some changes to the code on this page. The code samples on this page are written for the live StackBlitz editor. To work locally, see Set up LitElement. You can also download a sample LitElement project to get started.

1. Create a component

In this step, you’ll fill in the gaps in the starting code to create an element class with a basic HTML template.

Starting code

my-element.js

/**
 * Try LitElement https://lit-element.polymer-project.org/guide/try
 * Starting code for 1. Create
 */

/**
 * TODO: Import the LitElement base class and html helper function.
 */
import { } from ''; 

/**
 * TODO: Create a class for your element that extends the LitElement
 * base class.
 */
class MyElement { }    

/**
 * TODO: Register the new element with the browser.
 */
customElements.define();

Click Launch Code Editor to edit the starting code. When you’re ready to see your code in action, click Preview.

  1. Import the LitElement base class and html helper function.

    In my-element.js, replace the existing import statement with the following code:

    import { LitElement, html } from '@polymer/lit-element'; 
    
  2. Create a class for your element that extends the LitElement base class.

    In my-element.js, replace the existing class definition with the following code:

    class MyElement extends LitElement {
      render() {
        return html`
          <p>Hello world! From my-element</p>
        `;
      }
    }    
    

    The render function defines your component’s template. You must implement render for every LitElement component.

  3. Register the new element with the browser.

    In my-element.js, replace the existing call to customElements.define() with the following code:

    customElements.define('my-element', MyElement);
    

If you’re stuck, click Launch Code Editor below to see the completed code for Step 1.

2. Import your component

Import your new component as a JavaScript module and use it in a web page.

Starting code

index.html


<!-- 
  Try LitElement https://lit-element.polymer-project.org/guide/try
  Starting code for 2. Import
-->
<html>
  <head>
    <!-- Polyfills required for browser compatibility on StackBlitz -->
    <script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
    <script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
    <!-- In StackBlitz, my-element.js is imported in index.ts -->
    <!-- <script type="module" src="my-element.js"></script> -->
  </head>
  <body>
    <!-- TODO: Add your new element to the page -->
  </body>
</html>

  1. Import your component module.

    LitElement components are imported as JavaScript modules. You don’t need to change anything in this step if you’re following the tutorial in StackBlitz. In StackBlitz, index.ts runs automatically.

    index.ts

     // Import my-element module
    import './my-element.js';
    
    
  2. Add your new component to the page.

    In index.html, replace the existing body block with the following code:

       <body>
         <my-element></my-element>
       </body>
    

If you’re stuck, click Launch Code Editor below to see the completed code for Step 2.

3. Add a property to your template

Declare a property for your component, and use the value in the component’s template. LitElement components update automatically when their properties change.

Starting code

my-element.js

/**
 * Try LitElement https://lit-element.polymer-project.org/guide/try
 * Starting code for 3. Properties
 */

import { LitElement, html } from '@polymer/lit-element'; 

class MyElement extends LitElement {
  /**
   * TODO: Declare a property.
   */
  static get properties() {
    return { };
  }

  /**
   * TODO: Initialize the property.
   */
  constructor() {
    // Always call superconstructor first
    super(); 
  }

  /**
   * TODO: Add a property to your template with a JavaScript expression.
   */
  render() {
    return html`
      <p></p>
    `;
  }
}
customElements.define('my-element', MyElement);

  1. Declare a property.

    In my-element.js, replace the existing properties getter with the following code:

     static get properties() {
       return {
         // Property declaration
         message: { type: String }
       };
     }
    
  2. Initialize the property.

    You should initialize property values in a component’s constructor.

    In my-element.js, replace the existing constructor with the following code:

     constructor() {
       // Always call superconstructor first
       super();
    
       // Initialize property
       this.message='Hello world! From my-element';
     }
    
  3. Add the property to your template with a JavaScript expression.

    In my-element.js, replace the existing render function with the following code:

     render() {
       return html`
         <p>${this.message}</p>
       `;
     }
    

If you’re stuck, click Launch Code Editor below to see the completed code for Step 3.

4. Add loops and conditionals to your template

Modify your template to add a loop and a conditional.

Starting code

my-element.js

/**
 * Try LitElement https://lit-element.polymer-project.org/guide/try
 * Starting code for 4. Logic
 */

import { LitElement, html } from '@polymer/lit-element'; 

class MyElement extends LitElement {
  static get properties() {
    return {
      message: { type: String },
      myBool: { type: Boolean },
      myArray: {}
    };
  }
  constructor() {
    super();
    this.message='Hello world! From my-element';
    this.myBool = true;
    this.myArray = ['an','array','of','test','data'];
  }

  render() {
    return html`
      <p>${this.message}</p>

      <!-- TODO: Add a loop -->

      <!-- TODO: Add a conditional -->
    `;
  }
}
customElements.define('my-element', MyElement);

  1. Add a loop to your template.

    We’ve added an array property, myArray, to my-element.js. To loop over myArray, add the following code to your template:

     <ul>
       ${this.myArray.map(i => html`<li>${i}</li>`)}
     </ul>
    
  2. Add a conditional to your template.

    We’ve added a boolean property, myBool, to my-element.js. To render conditionally on myBool, add the following code to your template:

     ${this.myBool?
       html`<p>Render some HTML if myBool is true</p>`:
       html`<p>Render some other HTML if myBool is false</p>`}
    

If you’re stuck, click Launch Code Editor below to see the completed code for Step 4.

5. Add an event handler to your template

Use lit-html’s @event annotation to add an event listener to an element inside a template.

Starting code

my-element.js

/**
 * Try LitElement https://lit-element.polymer-project.org/guide/try
 * Starting code for 5. Events
 */

import { LitElement, html } from '@polymer/lit-element'; 

class MyElement extends LitElement {
  static get properties() {
    return {
      message: { type: String },
      myBool: { type: Boolean },
      myArray: {}
    };
  }
  constructor() {
    super();
    this.message='Hello world! From my-element';
    this.myArray = ['an','array','of','test','data'];
    this.myBool = true;
  }

  render() {
    return html`
      <p>${this.message}</p>
      <ul>
        ${this.myArray.map(i => html`<li>${i}</li>`)}
      </ul>
      ${this.myBool?
        html`<p>Render some HTML if myBool is true</p>`:
        html`<p>Render some other HTML if myBool is false</p>`}

      <!-- TODO: Add an event listener. -->
      <button>Click</button>
    `;
  }

  /**
   * TODO: Implement an event handler.
   */
}
customElements.define('my-element', MyElement);

  1. Add an event listener.

    In my-element.js, in your template, replace the existing HTML button element with the following code:

     <button @click="${(event) => this.clickHandler(event)}">Click</button>
    

    The annotation above adds a listener for the click event.

  2. Implement an event handler.

    To handle the click event, define the following method on your MyElement class:

     clickHandler(event) {
       console.log(event.target);
       this.myBool = !this.myBool;
     }
    

If you’re stuck, click Launch Code Editor below to see the completed code for Step 5.

6. Style your template

Style your element with CSS by including a style block in its template. These styles are encapsulated; they will only apply to your component.

Starting code

my-element.js

/**
 * Try LitElement https://lit-element.polymer-project.org/guide/try
 * Starting code for 6. Style
 */

import { LitElement, html } from '@polymer/lit-element'; 

class MyElement extends LitElement {
  static get properties() {
    return {
      message: { type: String },
      myArray: { type: Array },
      myBool: { type: Boolean }
    };
  }
  
  constructor() {
    super();
    this.message='Hello world! From my-element';
    this.myArray = ['an','array','of','test','data'];
    this.myBool = true;
  }

  render() {
    return html`
      <!-- TODO: Add a style block. -->

      <!-- TODO: Add a styled paragraph. -->

      <p>${this.message}</p>
      <ul>
        ${this.myArray.map(i => html`<li>${i}</li>`)}
      </ul>
      ${this.myBool?
        html`<p>Render some HTML if myBool is true</p>`:
        html`<p>Render some other HTML if myBool is false</p>`}
      <button @click="${(event) => this.clickHandler(event)}">Click</button>
    `;
  }

  clickHandler(event) {
    console.log(event.target);
    this.myBool = !this.myBool;
  }
}
customElements.define('my-element', MyElement);

  1. Define your styles.

    To define your styles, add the following code to your template:

    <style>
      p {
        font-family: Roboto;
        font-size: 16px;
        font-weight: 500;
      }
      .red {
        color: red;
      }
      .blue {
        color: blue;
      }
    </style>
    
  2. Apply your styles.

    Use myBool to apply the styles conditionally. Add the following paragraph to your template:

     <p class="${this.myBool?'red':'blue'}">styled paragraph</p>
    

If you’re stuck, click Launch Code Editor below to see the completed code for Step 6.

Next steps

Congratulations - you’ve made your first element with LitElement. Next, see the Tools documentation and Set up LitElement locally.