LogoLogo
HomeDiscourseBlogDiscord
  • Introduction
  • Introduction
    • Quick start
    • Aurelia for new developers
    • Hello world
      • Creating your first app
      • Your first component - part 1: the view model
      • Your first component - part 2: the view
      • Running our app
      • Next steps
  • Templates
    • Template Syntax
      • Attribute binding
      • Event binding
      • Text interpolation
      • Template promises
      • Template references
      • Template variables
      • Globals
    • Custom attributes
    • Value converters (pipes)
    • Binding behaviors
    • Form Inputs
    • CSS classes and styling
    • Conditional Rendering
    • List Rendering
    • Lambda Expressions
    • Local templates (inline templates)
    • SVG
  • Components
    • Component basics
    • Component lifecycles
    • Bindable properties
    • Styling components
    • Slotted content
    • Scope and context
    • CustomElement API
    • Template compilation
      • processContent
      • Extending templating syntax
      • Modifying template parsing with AttributePattern
      • Extending binding language
      • Using the template compiler
      • Attribute mapping
  • Getting to know Aurelia
    • Routing
      • @aurelia/router
        • Getting Started
        • Creating Routes
        • Routing Lifecycle
        • Viewports
        • Navigating
        • Route hooks
        • Router animation
        • Route Events
        • Router Tutorial
        • Router Recipes
      • @aurelia/router-lite
        • Getting started
        • Router configuration
        • Configuring routes
        • Viewports
        • Navigating
        • Lifecycle hooks
        • Router hooks
        • Router events
        • Navigation model
        • Transition plan
    • App configuration and startup
    • Enhance
    • Template controllers
    • Understanding synchronous binding
    • Dynamic composition
    • Portalling elements
    • Observation
      • Observing property changes with @observable
      • Effect observation
      • HTML observation
      • Using observerLocator
    • Watching data
    • Dependency injection (DI)
    • App Tasks
    • Task Queue
    • Event Aggregator
  • Developer Guides
    • Animation
    • Testing
      • Overview
      • Testing attributes
      • Testing components
      • Testing value converters
      • Working with the fluent API
      • Stubs, mocks & spies
    • Logging
    • Building plugins
    • Web Components
    • UI virtualization
    • Errors
      • 0001 to 0023
      • 0088 to 0723
      • 0901 to 0908
    • Bundlers
    • Recipes
      • Apollo GraphQL integration
      • Auth0 integration
      • Containerizing Aurelia apps with Docker
      • Cordova/Phonegap integration
      • CSS-in-JS with Emotion
      • DOM style injection
      • Firebase integration
      • Markdown integration
      • Multi root
      • Progress Web Apps (PWA's)
      • Securing an app
      • SignalR integration
      • Strongly-typed templates
      • TailwindCSS integration
      • WebSockets Integration
      • Web Workers Integration
    • Playground
      • Binding & Templating
      • Custom Attributes
        • Binding to Element Size
      • Integration
        • Microsoft FAST
        • Ionic
    • Migrating to Aurelia 2
      • For plugin authors
      • Side-by-side comparison
    • Cheat Sheet
  • Aurelia Packages
    • Validation
      • Validation Tutorial
      • Plugin Configuration
      • Defining & Customizing Rules
      • Architecture
      • Tagging Rules
      • Model Based Validation
      • Validation Controller
      • Validate Binding Behavior
      • Displaying Errors
      • I18n Internationalization
      • Migration Guide & Breaking Changes
    • i18n Internationalization
    • Fetch Client
      • Overview
      • Setup and Configuration
      • Response types
      • Working with forms
      • Intercepting responses & requests
      • Advanced
    • Event Aggregator
    • State
    • Store
      • Configuration and Setup
      • Middleware
    • Dialog
  • Tutorials
    • Building a ChatGPT inspired app
    • Building a realtime cryptocurrency price tracker
    • Building a todo application
    • Building a weather application
    • Building a widget-based dashboard
    • React inside Aurelia
    • Svelte inside Aurelia
    • Synthetic view
    • Vue inside Aurelia
  • Community Contribution
    • Joining the community
    • Code of conduct
    • Contributor guide
    • Building and testing aurelia
    • Writing documentation
    • Translating documentation
Powered by GitBook
On this page
  • An introduction to enhance
  • Basic Syntax and Key Points
  • Enhancing During Application Startup
  • Enhancing on the fly within components

Was this helpful?

Export as PDF
  1. Getting to know Aurelia

Enhance

Learn how to use Aurelia with existing HTML (inside of other frameworks and libraries), hydrating server-generated HTML or running multiple instances of Aurelia in your application.

PreviousApp configuration and startupNextTemplate controllers

Last updated 1 year ago

Was this helpful?

An introduction to enhance

Enhancement in Aurelia allows for integrating Aurelia’s capabilities with existing DOM elements or dynamically inserted HTML content. This feature is particularly useful in scenarios where the application is not entirely built with Aurelia, such as when integrating with server-rendered pages or dynamically generated content.

The showed how to start Aurelia for an empty root node. While that's the most frequent use case, there might be other scenarios where we would like to work with an existing DOM tree with Aurelia.

Basic Syntax and Key Points

The basic usage of enhance is straightforward:

const au = new Aurelia();
await au.enhance({ host, component: MyComponent });

Key Points to Understand:

  1. Anonymous Custom Element Hydration: The enhancement treats the target node as an anonymous custom element, allowing Aurelia to apply its behavior to the existing DOM structure.

  2. Component Flexibility: The component parameter in enhance can be a custom element class, a class instance, or an object literal. If a class is provided, it's instantiated by Aurelia's dependency injection container, which can be either provided or automatically created.

  3. Host Element: The host is typically an existing DOM node that is not yet under Aurelia's control. It's crucial to note that enhance ' neither detaches nor attaches the hostto the DOM. Existing event handlers on thehost` or its descendants remain unaffected.

  4. Controller Deactivation: an enhance call results in an application root that requires manual deactivation or integration into an existing controller hierarchy for automatic framework management.

Example of deactivating an application root:

const root = au.enhance({ host, component });
root.deactivate();

Enhancing During Application Startup

Enhance can be particularly useful during application startup, especially when integrating Aurelia into an existing web page or alongside other frameworks.

Let's create an index.html file containing some HTML markup you would encounter if you generated an Aurelia application using npx makes aurelia or other means.

Pay attention to the contents of the <body> as there is a container called app as well as some HTML tags <my-app>

index.html
<body>
  <div id="app">
    <my-app></my-app>
  </div>
</body>

Now, let's enhance our application by using the enhanceAPI inside of main.ts

import Aurelia from 'aurelia';
import { MyApp } from './my-app';
try {
Aurelia
  .register(MyApp)
  .enhance({
      host: document.querySelector('div#app'),
      component: {},
  });
} catch (error) {
  console.error(error);
}

Or if your component has one of its lifecycle return a promise:

import Aurelia from 'aurelia';
import { MyApp } from './my-app';

;(async () => {
  try {
    await Aurelia
      .register(MyApp)
      .enhance({
          host: document.querySelector('div#app'),
          component: {},
      });
  } catch (error) {
    console.error(error);
  }
})();

We first wrap our async code in an anonymous async function. This allows us to catch errors and throw them to the console if enhancement fails, but take note of the enhance call itself. We supply the host element (in our case, it's a DIV with an ID of app as the host).

Above our enhance call, we register our main component, MyApp, the initial component our application will render.

Pay attention to what you are enhancing. Please make sure you are enhancing the container and not the component itself. It's an easy mistake, and we have seen some developers get caught on.

This approach will work for existing applications as well. Say you have a WordPress website and want to create an Aurelia application on a specific page. You could create a container and pass the element to the host on the enhance call.

Enhancing on the fly within components

While using the enhance during registration, the enhance API is convenient for situations where you want to control how an Aurelia application is enhanced. There are times when you want to enhance HTML programmatically from within components. This may be HTML loaded from the server or elements created on the fly.

In the following example, we query our markup for an item-list element and insert some Aurelia-specific markup into it (a repeater).

import Aurelia, { IAurelia, resolve } from 'aurelia';

export class MyApp {
  items = [1, 2, 3];

  constructor(private readonly au = resolve(Aurelia)) {}

  attached() {
    const itemList = document.getElementById('item-list');
    itemList.innerHTML = "<div repeat.for='item of items'>${item}</div>";

    this.au.enhance({
      component: { items: this.items },
      host: itemList,
    });
  }
}

As you can see, we are dynamically injecting some HTML into an existing element. Because this is being done after Aurelia has already compiled the view, it would not work. This is why we must call enhance to tell Aurelia to parse our inserted HTML.

You can use this approach to enhance HTML inserted into the page after initial compilation, which is perfect for server-generated code.

startup sections