# Override a Custom Element

**URL:** <https://discourse.aurelia.io/t/override-a-custom-element/3943>\
**Category:** Help Requests\
**Created:** [December 22, 2020, 12:51pm UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943 "2020-12-22T12:51:33Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![JSeligsohn](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jseligsohn/32/1964_2.png) [@JSeligsohn](https://discourse.aurelia.io/u/JSeligsohn)\
**Post date:** [December 22, 2020, 12:51pm UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/1 "2020-12-22T12:51:33Z")

</div>

I’ve been researching how to do the following, but haven’t seen a direct solution:

The challenges are two fold:

1. Be able to specify which custom element to use at runtime. In other words, custom elements are used throughout my app, but I’d like to specify whether to use implementation A or B of that custom element.  
Example:  
The component is used here:

```auto
<template>
  <hello-world></hello-world>
</template>

```

And I have two (or more) possible implementations of `<hello-world>` custom element.  
A)

```auto
export class HelloWorld {
  message: string = "Hello World!"
}

//HTML
<template>
<h1>${message}</h1>
</template>

```

B)

```auto
export class HelloWorld {
  message: string = "Goodbye World!"
}

//HTML
<template>
<h1>My message: ${message}</h1>
</template>

```

1. To make things more complicated, the “code” for the custom element is not part of the codebase of my app but loaded dynamically from an external resource. Is this even possible to achieve? Can a class/implementation (that happens to be valid “aurelia code”) be loaded from outside of aurelia and set as a custom element? I know there’s a way to register global resources, but I would think those resources have to exist/be defined already within the app.  
I’m using webpack, so I fear this is even more difficult, if not impossible to do.

Any direction or advice would be much appreciated.  
Thank you.

---

<div class="post-metadata">

**Author:** ![Sayan751](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/sayan751/32/1861_2.png) [@Sayan751](https://discourse.aurelia.io/u/Sayan751)\
**Post date:** [December 22, 2020, 8:08pm UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/2 "2020-12-22T20:08:04Z")

</div>

Assuming you want to override the markup for a given view-model class registering a inline view strategy for the class probably will do the job.

```auto
import {metadata} from 'aurelia-metadata';
import {ViewLocator} from 'aurelia-templating';

const strategy = new InlineViewStrategy(markup, undefined, undefined); // <-- `markup` contains the HTML string
metadata.define(ViewLocator.viewStrategyMetadataKey, strategy, HelloWorld);

```

I think defining the metadata in that way in the bootstrapping phase might work. Note that this code is mostly hypothetical, and not tested. Refer the `@inlineView` source for more details.

> <https://github.com/aurelia/templating/blob/aacb53449aed97b48b3ca55b51d169ebf921f5ef/src/decorators.js#L217-L226>

If the backing view model class also changes, and you still need a constant CE name, you might need to define the metadata for that as well. See below.

> <https://github.com/aurelia/templating/blob/aacb53449aed97b48b3ca55b51d169ebf921f5ef/src/decorators.js#L41-L50>

I have assumed that you are not yet using Aurelia2. IMO these sort of things will be very easy in Aurelia2.

Would you be able to share the reason why you want to do this BTW?

---

<div class="post-metadata">

**Author:** ![zewa666](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/zewa666/32/19_2.png) [@zewa666](https://discourse.aurelia.io/u/zewa666)\
**Post date:** [December 23, 2020, 4:58am UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/3 "2020-12-23T04:58:45Z")

</div>

The compose element might be another way to solve your issue by allowing to specify a dynamic view and viewmodel. If the backing Code is no full view, create a viewmodel that will act as wrapper and inside its activate Hook load your data and return a promise once done. Take a look at the docs about compose to get a few ideas

---

<div class="post-metadata">

**Author:** ![JSeligsohn](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jseligsohn/32/1964_2.png) [@JSeligsohn](https://discourse.aurelia.io/u/JSeligsohn)\
**Post date:** [December 23, 2020, 10:17am UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/4 "2020-12-23T10:17:58Z")

</div>

Thanks for your help!  
Yes, I would need to override both the markup and view model. I’ll take a look at what you suggested.  
As far as Aurelia2 - I’m currently using Aurelia 1, but would be open to switching to Aurelia 2. Do you know what I should look at there to achieve the same result?

---

<div class="post-metadata">

**Author:** ![JSeligsohn](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jseligsohn/32/1964_2.png) [@JSeligsohn](https://discourse.aurelia.io/u/JSeligsohn)\
**Post date:** [December 23, 2020, 10:21am UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/5 "2020-12-23T10:21:03Z")

</div>

In terms of a use case, imagine the following:  
I have a platform with core components used throughout the app. A client or third party would like to customize this app and provide an alternative implementation of any of the components used in the app. I don’t want their code living inside my codebase and would prefer to load their implementations of the components separately.  
Do you have a better way to achieve this?

---

<div class="post-metadata">

**Author:** ![JSeligsohn](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jseligsohn/32/1964_2.png) [@JSeligsohn](https://discourse.aurelia.io/u/JSeligsohn)\
**Post date:** [December 23, 2020, 10:23am UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/6 "2020-12-23T10:23:25Z")

</div>

Thanks for the suggestion. I’d prefer not to use “compose” because then I essentially would have to use compose elements everywhere instead of custom elements. Other than a lack of clarity/organization, I think that would pose some additional challenges as well as custom elements are implemented a bit differently than compose elements, as far as I understand.

---

<div class="post-metadata">

**Author:** ![Sayan751](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/sayan751/32/1861_2.png) [@Sayan751](https://discourse.aurelia.io/u/Sayan751)\
**Post date:** [December 23, 2020, 10:40am UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/7 "2020-12-23T10:40:05Z")

</div>

You have an interesting use case. I am assuming that you have a root level basic markup with fixed names for the custom elements.

For example, in you base markup you have

```html
<foo-bar></foo-bar>
<fizz-buzz></fizz-buzz>

```

and then you want the client to provide the impl. for `foo-bar` and `fizz-buzz`. Is that correct?

If so then with Au2 achieving that is a breeze due existence of first-class APIs to do this kind of things. With Au2 it might look something like this.

```ts
container
  .register(
    CustomElement.define({name: 'foo-bar', template: fooBarTemplate}, FooBarImpl),
    CustomElement.define({name: 'fizz-buzz', template: fizzBuzzTemplate}, FizzBuzzImpl),
  )

```

Although the example shown is verbose it offers max flexibility. To know more about Aurelia2 refer the [docs](https://docs.aurelia.io/). Note that although it is pretty stable, it still is a work in progress.

On a second thought, there might be even easier solution for your use-case. If the client always owns the markup as well as backing viewmodel class, then there is no need for this gymnastic. Especially if you provide the “framework” part of it, and the client provides the “app” part of it. The details lies here

> A client or third party would like to customize this app

The question is how the client will customize it exactly?

---

<div class="post-metadata">

**Author:** ![JSeligsohn](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jseligsohn/32/1964_2.png) [@JSeligsohn](https://discourse.aurelia.io/u/JSeligsohn)\
**Post date:** [December 23, 2020, 11:39am UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/8 "2020-12-23T11:39:24Z")

</div>

That’s great news about Aurelia2. I’ll have to look into that more.  
Would registering the components work in the example you provided if I loaded the actual markup/viewmodel/class from an external resource, or do the references (like `fooBarTemplate`) have to alright exist in the compiled code?

The client doesn’t own the app part either - it’s a single instance of the platform/app. They would be able to provide an external script/file that is loaded into the app, that specifies and contains the components they would like to override, including the source code for said components.

---

<div class="post-metadata">

**Author:** ![zewa666](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/zewa666/32/19_2.png) [@zewa666](https://discourse.aurelia.io/u/zewa666)\
**Post date:** [December 23, 2020, 1:56pm UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/9 "2020-12-23T13:56:25Z")

</div>

Would it be possible for the client to offer an Aurelia Plugin instead which your app is using? Or is his code too dynamic or the approach to cumbersome?

---

<div class="post-metadata">

**Author:** ![JSeligsohn](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jseligsohn/32/1964_2.png) [@JSeligsohn](https://discourse.aurelia.io/u/JSeligsohn)\
**Post date:** [December 23, 2020, 2:40pm UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/10 "2020-12-23T14:40:48Z")

</div>

I’d consider the Aurelia Plugin approach, but can you elaborate on how that would work? Would the plugin make it easier to override existing custom elements? How are you thinking the plugin would work?

---

<div class="post-metadata">

**Author:** ![zewa666](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/zewa666/32/19_2.png) [@zewa666](https://discourse.aurelia.io/u/zewa666)\
**Post date:** [December 23, 2020, 4:07pm UTC](https://discourse.aurelia.io/t/override-a-custom-element/3943/11 "2020-12-23T16:07:43Z")

</div>

Well with the plugin approach they could provide the whole component at once or just parts like the ViewModel. Essentially they get a sub-app to go crazy and expose whatever is necessary and you include that during Plugin setup. The main benefit I see with that is that the client wouldnt be limited to solely that one custom element but could provide whatever necessary plus have a test-environment to check things outside your app.

As for the general question of one name but two elements. I would just ditch that. Let them namespace their elements like `client-hello-world` and you decide what to show original or client hello world. If you insist though, above scenario from @Sayan751 could still work
