AUR0717

Template compilation error: detected a usage of "<slot>" element without specifying shadow DOM options in element yyyy

Error message

Template compilation error: detected a usage of "<slot>" element without specifying shadow DOM options in element: {{0}}

Parameters

  1. elementName: The name of the custom element where the <slot> was found.

Error explanation

This error occurs during template compilation when a <slot> element is used within a custom element's template, but the custom element has not been configured to use Shadow DOM. The native <slot> element is part of the Shadow DOM specification and only functions correctly when the component has shadowOptions defined.

Aurelia's au-slot attribute provides a slotting mechanism that works without Shadow DOM, but the native <slot> element requires it.

Common causes

  • Using <slot> (or <slot name="...">) in a custom element's template without setting shadowOptions in the element's definition.

  • Migrating from a framework where <slot> might work without Shadow DOM, or confusing it with Aurelia's au-slot attribute for content projection.

How to fix

  • Option 1 (Use Shadow DOM): If you intend to use native Shadow DOM slots, add shadowOptions to your custom element definition:

    import { customElement } from 'aurelia';
    
    @customElement({
      name: 'my-element',
      template: `<template><slot></slot></template>`,
      shadowOptions: { mode: 'open' } // or 'closed'
    })
    export class MyElement { }
  • Option 2 (Use au-slot for projection without Shadow DOM): If you do not want to use Shadow DOM, replace the <slot> element in your template with the target element where you want projected content to appear, and use the au-slot attribute on the content being projected when using the component. Aurelia's default slot projection mechanism (without explicit <slot> tags in the component template) often handles simple cases automatically.

Example of Incorrect Usage:

// my-element.ts
import { customElement } from 'aurelia';

@customElement({
  name: 'my-element',
  // Error: Using <slot> without shadowOptions
  template: `<template><div><slot></slot></div></template>`
})
export class MyElement { }

Example of Correct Usage (with Shadow DOM):

// my-element.ts
import { customElement } from 'aurelia';

@customElement({
  name: 'my-element',
  template: `<template><div><slot></slot></div></template>`,
  shadowOptions: { mode: 'open' } // Correct: Shadow DOM enabled
})
export class MyElement { }

Example of Correct Usage (without Shadow DOM, using au-slot projection):

// my-element-no-shadow.ts
import { customElement } from 'aurelia';

@customElement({
  name: 'my-element-no-shadow',
  // Template simply defines where content *could* go,
  // but relies on default projection or specific logic.
  // No <slot> element is needed here for basic projection.
  template: `<template><div><au-content></au-content></div></template>`
  // Note: <au-content> is a placeholder for where default
  // projected content goes if no specific slot logic is needed.
  // Often, you might just have bindables and structure.
})
export class MyElementNoShadow { }
<!-- usage.html -->
<import from="./my-element-no-shadow"></import>

<my-element-no-shadow>
  This content will be projected into my-element-no-shadow
  where the default slot/content area is.
</my-element-no-shadow>

Last updated

Was this helpful?