Packaging app in a web component

Just doing some experimenting and trying to package an aurelia app in a web component.

e.g.

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

export default class MyWebComponentApp extends HTMLElement {
  constructor() {
    super()

    this.attachShadow({ mode: 'open' })

    this.shadowRoot!.innerHTML = '<my-app></my-app>'
  }

  async connectedCallback() {
    const host = this.shadowRoot!.querySelector('my-app') as HTMLElement

    Aurelia
      .app({ host: host, component: MyApp })
      .start()
  }
}

customElements.define('my-web-component-app', MyWebComponentApp)

Seems to be working, but aurelia adds stylesheets to the head tag of the page, rather than to the shadow root. Anyay to overcome this?

Here is a repo to test it out: GitHub - ivanbacher/root-web-component

This is because Aurelia doesn’t know you’re instantiating the app inside of a web component. It won’t traverse the DOM and determine if the root is shadow or not.

You’ll need to make your my-app component a shadow component:

// my-app.ts
import { customElement, shadowCSS, useShadowDOM } from 'aurelia';
import template from './my-app.html';
import styles from './my-app.css';

@useShadowDOM({ mode: 'open' })
@customElement({
  name: 'my-app',
  template,
  dependencies: [shadowCSS(styles)]
})
export class MyApp {
  message = 'Hello World!';
}

Thanks for the info @dwaynecharrington. I gave it a go, and this brought up some more questions. Maybe you can answer them :slightly_smiling_face:.

I updated my-app to the version below.

import { customElement, shadowCSS, useShadowDOM } from 'aurelia'
import template from './my-app.html'
import styles from './my-app.css?raw'

import { ComponentOne } from './components/component-one'
import { ComponentTwo } from './components/component-two'

@customElement({
  name: 'my-app',
  template,
  dependencies: [shadowCSS(styles), ComponentOne, ComponentTwo]
})

@useShadowDOM({ mode: 'open' })


export class MyApp {
  public message = 'Hello World!'
}

This is working, but my-app.css is still being added to the head tag of the page. Is this the intended behaviour?

I also need to register all additional components that my-app uses and the css of these components gets added to the head tag, but this is probably because I need to also make them shadow components?

Also this fail’s to build in Vite due to a HTML parsing error ( this might be more of a Vite issue?)

[vite:build-html] Unable to parse HTML; parse5 error code unexpected-character-in-unquoted-attribute-value
 at /Users/.../Desktop/root-web-component/src/my-app.html:6:44

export const name = "my-app";
export const template = "\n\n\n<div class=\"message\">${message}</div>\n\n<component-one></component-one>\n<component-two></component-two>";

I updated the repo: GitHub - ivanbacher/root-web-component

This might just be an stupid use case. Feel free to let me know if this sis the case. Thanks for your time.