Component basics

Components are the building blocks of Aurelia applications. This guide covers creating, configuring, and using components effectively.

Components are the core building blocks of Aurelia applications. Each component typically consists of:

  • A TypeScript class (view model)

  • An HTML template (view)

  • Optional CSS styling

Component Naming

Component names must include a hyphen (e.g., user-card, nav-menu) to comply with Web Components standards. Use a consistent prefix like app- or your organization's initials for better organization.

Creating Your First Component

The simplest way to create a component is with convention-based files:

export class UserCard {
  name = 'John Doe';
  email = '[email protected]';
}

Aurelia automatically pairs user-card.ts with user-card.html by convention, creating a <user-card> element you can use in templates.

Component Configuration

Use the @customElement decorator for explicit configuration:

import { customElement } from 'aurelia';

@customElement({
  name: 'user-card',
  template: `
    <div class="user-card">
      <h3>\${name}</h3>
      <p>\${email}</p>
    </div>
  `
})
export class UserCard {
  name = 'John Doe';
  email = '[email protected]';
}

For simple naming, use the shorthand syntax:

Configuration Options

Key @customElement options:

Template Configuration:

Importing external HTML templates with bundlers

When a component imports an .html file, the bundler must deliver that file as a plain string. Otherwise tools such as Vite, Webpack, and Parcel try to parse the file as an entry point and emit errors like [vite:build-html] Unable to parse HTML; parse5 error code unexpected-character-in-unquoted-attribute-value or "template" is not exported by src/components/product-name-search.html.

Configure your bundler using the option that best matches your stack:

  • Vite / esbuild (default Aurelia starter), Parcel 2, Rollup + @rollup/plugin-string – append ?raw to the import so the bundler treats the file as text:

    Add a matching declaration so TypeScript understands these imports (the query string can be reused for other text assets):

  • Webpack 5 – mark .html files as asset/source (or keep using raw-loader). After that you can import without a query parameter:

  • Other bundlers – use the equivalent “treat this file as a string” hook (e.g., SystemJS text plugin).

Once the bundler understands .html files as text, both npm start and npm run build can reuse the same component source without inline templates. Keep the import pattern consistent across the project so contributors immediately know which loader configuration applies.

Dependencies:

Alternative Creation Methods

Static Configuration:

Programmatic (mainly for testing):

HTML-Only Components

Create simple components with just HTML:

Usage:

Viewless Components

Components that handle DOM manipulation through third-party libraries:

Using Components

Global Registration (in main.ts):

Local Import (in templates):

Containerless Components

Render component content without wrapper tags:

Or configure inline:

Component Lifecycle

Components follow a predictable lifecycle. Implement only the hooks you need:

See Component Lifecycles for comprehensive lifecycle documentation.

Bindable Properties

Components accept data through bindable properties:

See Bindable Properties for complete configuration options.

Advanced Features

Shadow DOM

Enable Shadow DOM for complete style and DOM encapsulation:

Shadow DOM is useful for:

  • Complete style isolation (styles won't leak in or out)

  • Creating reusable components with predictable styling

  • Using native <slot> elements for content projection

  • Building design systems and component libraries

See the Shadow DOM guide for detailed configuration, styling patterns, and best practices.

Template Processing

Transform markup before compilation:

Enhancing Existing DOM

Apply Aurelia to existing elements:

Reactive Properties

Watch for property changes:

Child Element Observation

Component Configuration

Attribute Capture:

Aliases:

Best Practices

Component Design

  • Single Responsibility: Each component should have one clear purpose

  • Type Safety: Use interfaces for complex data structures

  • Composition: Favor composition over inheritance

Performance

  • Use attached() for DOM-dependent initialization

  • Clean up subscriptions in detaching()

  • Prefer @watch over polling for reactive updates

  • Consider Shadow DOM for style isolation

Testing

  • Mock dependencies properly

  • Test lifecycle hooks and bindable properties

  • Write tests for error scenarios

See Testing Components for detailed guidance.


Components form the foundation of Aurelia applications. Start with simple convention-based components and add complexity as needed. The framework's flexibility allows you to adopt patterns that fit your project's requirements while maintaining clean, maintainable code.

Last updated

Was this helpful?