Skip to content

Building a Web Component for Polyfea

In this tutorial, you'll create a reusable web component using the Lit framework. This component will serve as a microfrontend container with two polyfea-context elements, demonstrating how to build composable interfaces for the Polyfea platform.

What You'll Build

  • A grid-based container component with two Polyfea context areas
  • A reusable tile component that can be dynamically loaded into context areas
  • TypeScript-based web components with proper type declarations

Prerequisites

  • Node.js (v16+) and npm installed
  • Basic understanding of TypeScript and web components
  • Familiarity with Lit framework (recommended)

Step 1: Set Up the Lit Starter Kit

Clone the Lit TypeScript starter:

git clone https://github.com/lit/lit-element-starter-ts.git my-polyfea-component
cd my-polyfea-component

Install dependencies:

npm install

Step 2: Build and Test the Starter

Verify the setup works:

npm run build
npm run start

You should see the Component Demo page in your browser. The default component demonstrates Lit's basic functionality.

Step 3: Create the Container Component

We'll modify my-element.ts to create a grid layout with two polyfea-context elements.

Update src/my-element.ts:

/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: BSD-3-Clause
 */

import {LitElement, html, css} from 'lit';
import {customElement} from 'lit/decorators.js';

/**
 * A container element with two polyfea-context areas arranged in a grid.
 *
 * @slot - This element has a slot
 */
@customElement('my-element')
export class MyElement extends LitElement {
  static override styles = css`
    .grid-container {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 16px;
    }

    .grid-container > div {
      width: 300px;
      height: 200px;
      border: 1px solid #ccc;
      padding: 8px;
    }
  `;

  override render() {
    return html`
      <div class="grid-container">
        <div>
          <polyfea-context name="left"></polyfea-context>
        </div>
        <div>
          <polyfea-context name="right"></polyfea-context>
        </div>
      </div>
    `;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'my-element': MyElement;
  }
}

What's Happening Here?

  • Grid Layout: Creates a 2-column responsive grid
  • polyfea-context Elements: These are Polyfea's dynamic loading zones where microfrontends will be injected at runtime
  • Named Contexts: The name attribute (left and right) identifies each context area for targeted component loading

Step 4: Build a Tile Component

Create a reusable tile component that can be dynamically loaded into the context areas.

Create src/my-tile-element.ts:

/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: BSD-3-Clause
 */

import {LitElement, html, css} from 'lit';
import {customElement, property} from 'lit/decorators.js';

/**
 * A simple tile/card component with centered bold text.
 *
 * @property {string} text - The text to display in the tile
 */
@customElement('my-tile')
export class MyTile extends LitElement {
  @property({type: String})
  text = '';

  static override styles = css`
    :host {
      display: block;
    }

    .tile {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 200px;
      height: 150px;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      border-radius: 12px;
      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
      padding: 20px;
      transition: transform 0.2s, box-shadow 0.2s;
    }

    .tile:hover {
      transform: translateY(-4px);
      box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
    }

    .text {
      font-weight: bold;
      font-size: 1.5rem;
      color: white;
      text-align: center;
      word-break: break-word;
    }
  `;

  override render() {
    return html`
      <div class="tile">
        <div class="text">${this.text}</div>
      </div>
    `;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'my-tile': MyTile;
  }
}

Tile Component Features

  • Reactive Property: The text property updates the display when changed
  • Shadow DOM Styling: Styles are encapsulated and won't conflict with other components
  • Hover Effects: Smooth animations enhance user interaction
  • Gradient Background: Modern visual design with purple gradient

Step 5: Test Locally (Optional)

To see your components in action during development, update your index.html to import the tile component:

<script type="module" src="./src/my-element.js"></script>
<script type="module" src="./src/my-tile-element.js"></script>

<my-element></my-element>

Start the dev server:

npm run start

Note: For this tutorial, we're focusing on building the components. Local testing with polyfea-context requires the Polyfea runtime, which we'll set up in the Kubernetes deployment tutorial.

Step 6: Build the Project

We will use minimal build configuration since we want to showcase the import maps feature of modern browsers and also how it is implemented in Polyfea.

Build the project:

npm run build

What's Next?

You've successfully created two web components:

  • my-element: A container with Polyfea context areas
  • my-tile: A reusable tile component with properties

In the next tutorial, you'll learn how to:

  • Containerize these components in a Docker image
  • Serve them with nginx
  • Push the image to a container registry

Summary

This tutorial covered:

  • Setting up a Lit TypeScript project
  • Creating a grid-based container with polyfea-context elements
  • Building a reusable tile component with reactive properties
  • Proper TypeScript type declarations for custom elements

Your components are now ready to be packaged and deployed as Polyfea microfrontends!