Claude Code Plugins

Community-maintained marketplace

Feedback

Define and use custom HTML elements. Use when creating new components, defining custom tags, or using project-specific elements beyond standard HTML5.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name custom-elements
description Define and use custom HTML elements. Use when creating new components, defining custom tags, or using project-specific elements beyond standard HTML5.
allowed-tools Read, Write, Edit, Bash

Custom Elements Skill

This skill provides guidance for defining and using custom HTML elements in this project.

Two Definition Systems

System File Purpose
HTML Validation .claude/schemas/elements.json Validates custom elements in HTML (html-validate)
Custom Elements Manifest custom-elements.json Documents components for IDEs, Storybook, docs

Both are recommended - elements.json for build-time HTML validation, CEM for runtime tooling.

See MANIFEST.md for Custom Elements Manifest generation.

Using Existing Elements

Check .claude/schemas/elements.json for defined custom elements:

Element Type Purpose
product-card Block Product display with sku, price attributes
icon-element Void Self-closing icon with required name attribute
user-avatar Void Avatar with required src, alt and optional size
status-badge Inline Status indicator with type (success/warning/error/info)
data-table Block Data table with source, sortable attributes
nav-menu Block Navigation with orientation (horizontal/vertical)

Usage Examples

<!-- Product card with attributes -->
<product-card sku="ABC123" price="29.99">
  <h2>Product Name</h2>
  <p>Product description here.</p>
</product-card>

<!-- Void element (self-closing) -->
<icon-element name="star"/>
<user-avatar src="/avatar.jpg" alt="John Doe" size="medium"/>

<!-- Inline element -->
<p>Status: <status-badge type="success">Active</status-badge></p>

<!-- Block elements -->
<nav-menu orientation="horizontal">
  <ul>
    <li><a href="/">Home</a></li>
  </ul>
</nav-menu>

<data-table source="/api/users" sortable="">
  <!-- Table content -->
</data-table>

Ad-hoc Custom Elements

For one-off custom elements not worth defining in .claude/schemas/elements.json, use the x-* prefix:

<x-highlight>Important text</x-highlight>
<x-tooltip data-text="Help text">Hover me</x-tooltip>
<x-badge>New</x-badge>

The x-* pattern is excluded from validation by default.

Defining New Elements

Using Slash Command

/add-element my-widget

Manual Definition

Add to .claude/schemas/elements.json:

{
  "my-element": {
    "flow": true,
    "phrasing": false,
    "permittedContent": ["@flow"],
    "attributes": {
      "required-attr": { "required": true },
      "optional-attr": { "required": false }
    }
  }
}

Element Schema Reference

Content Model

Property Values Description
flow boolean Can appear where flow content is expected
phrasing boolean Can appear where phrasing content is expected
void boolean Self-closing element (no content)
permittedContent array What content is allowed inside

Permitted Content Values

  • @flow - Flow content (most elements)
  • @phrasing - Phrasing content (inline elements)
  • @interactive - Interactive elements
  • ["p", "div"] - Specific elements only

Attribute Definitions

{
  "attributes": {
    "name": {
      "required": true           // Must be present
    },
    "type": {
      "required": false,
      "enum": ["a", "b", "c"]    // Restricted values
    },
    "enabled": {
      "boolean": true            // Boolean attribute
    }
  }
}

Complete Examples

Block Element

{
  "card-component": {
    "flow": true,
    "phrasing": false,
    "permittedContent": ["@flow"],
    "attributes": {
      "variant": {
        "required": false,
        "enum": ["default", "outlined", "elevated"]
      },
      "clickable": {
        "boolean": true
      }
    }
  }
}

Usage:

<card-component variant="elevated" clickable="">
  <h2>Card Title</h2>
  <p>Card content</p>
</card-component>

Void Element

{
  "loading-spinner": {
    "void": true,
    "flow": true,
    "phrasing": true,
    "attributes": {
      "size": {
        "enum": ["small", "medium", "large"]
      }
    }
  }
}

Usage:

<loading-spinner size="medium"/>

Inline Element

{
  "price-tag": {
    "flow": true,
    "phrasing": true,
    "permittedContent": ["@phrasing"],
    "attributes": {
      "currency": {
        "required": false,
        "enum": ["USD", "EUR", "GBP"]
      }
    }
  }
}

Usage:

<p>Price: <price-tag currency="USD">29.99</price-tag></p>

Naming Conventions

  • Use lowercase with hyphens: my-element
  • Names must contain a hyphen (web component spec)
  • Be descriptive: product-card not pc
  • Use consistent prefixes for related elements: form-input, form-select, form-button

Related Skills

  • javascript-author - Write vanilla JavaScript for Web Components with function...
  • data-attributes - Using data-* attributes as the HTML/CSS/JS bridge for sta...
  • state-management - Client-side state patterns for Web Components
  • accessibility-checker - Ensure WCAG2AA accessibility compliance