# Au2 migration - replace-part

**URL:** <https://discourse.aurelia.io/t/au2-migration-replace-part/6328>\
**Category:** Help Requests\
**Created:** [January 17, 2025, 1:58pm UTC](https://discourse.aurelia.io/t/au2-migration-replace-part/6328 "2025-01-17T13:58:53Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Haltesh](https://avatars.discourse-cdn.com/v4/letter/h/f0a364/32.png) [@Haltesh](https://discourse.aurelia.io/u/Haltesh)\
**Post date:** [January 17, 2025, 1:58pm UTC](https://discourse.aurelia.io/t/au2-migration-replace-part/6328/1 "2025-01-17T13:58:53Z")

</div>

I’m trying to migrate a relatively large app from Aurelia 1 to Aurelia2, and I’m very confused about how to migrate code that relied on `replaceable/replace-part`. The documentation seems to imply that that functionality has been replaced by `<au-slot>`, but that seems disingenuous.

The functionality that `<au-slot>` provides is the same functionality that the old `<slot>` element provided. `replaceable/replace-part` was, to my knowledge, the only thing in aurelia that allowed a parent component to specify a template that a reusable component could use to modify how items are rendered in its own repeat.for list.

That meant you could do stuff like this (simplified) select component:

my-select.html:

```auto
 <div repeat.for="option of options" click.delegate="onOptionClick(option)">
    <template with.bind="option" part="optionTemplate" replaceable></template>
 </div>

```

app.html

```auto
<my-select options.bind="options">
    <template replace-part="optionTemplate">
        ${option.code} - ${option.title}
    </template>
</my-select

```

Or a translation component with replaceable placeholders:

my-translation.ts:

```auto
import { bindable, bindingMode, computedFrom } from 'aurelia-framework';

export class MyTranslationCustomElement {
    @bindable({ defaultBindingMode: bindingMode.toView})
    public value: string = '';

    @computedFrom('value')
    public get parts() {
        return this.createParts(this.value);
    }

    // PRIVATE
    private createParts(value: string) {
        const regex = /\{\d+\}/gi;
        const parts = value.match(regex);

        if (!parts || parts.length === 0 ) {
            return [{
                type: 'text',
                value: value
            }];
        }

        const output: TranslationPart[] = [];
        let index: number = undefined;
        let lastIndex: number = undefined;

        parts.forEach(part => {
            index = value.indexOf(part, lastIndex);
            lastIndex = lastIndex || 0;
            
            if (index > lastIndex) {
                output.push({
                    type: 'text',
                    value: value.substring(lastIndex, index)
                });
            }

            output.push({
                type: 'replacement',
                value: part
            });
    
            lastIndex = index + part.length;
        });
        
        if (lastIndex < value.length) {
            output.push({
                type: 'text',
                value: value.substring(lastIndex, value.length)
            });
        }

        return output;
    }
}

interface TranslationPart {
    type: 'text'|'replacement';
    value: string;
}

```

my-translation.html:

```auto
<template>
    <template repeat.for="part of parts"><template if.bind="part.type === 'text'">${part.value}</template><au-slot else name.bind="part.value">${part.value}</au-slot></template>
</template>

```

app.html:

```auto
<my-translation template.bind="'Replace {0} and {1} with slotted content'">
    <template replace-part="placeholder">
       <b if.bind="part.value === '{0}'">THIS</b>
       <a if.bind="part.value === '{1}'" href="#">THAT</<>
    </template>
</my-translation>

```

How can I replicate any of this in Aurelia 2?

---

<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:** [January 18, 2025, 4:00pm UTC](https://discourse.aurelia.io/t/au2-migration-replace-part/6328/2 "2025-01-18T16:00:46Z")

</div>

Hi! If I am not mistaken, your example of selection can be translated using `au-slot` as follows.

```html
<!--my-select.html-->
<div repeat.for="option of options" click.delegate="onOptionClick(option)">
    <au-slot name="optionTemplate"></au-slot>
 </div>

```

```html
<!-- app.html -->
<my-select options.bind="options">
    <template au-slot="optionTemplate">
        ${option.code} - ${option.title}
      <!--
           if your app also has a property named `option`,  
           or you want to explicitly grab the context of `my-select`
           then you need to use `$host.option` instead.
      -->
    </template>
</my-select>

```

In case, you have not yet checked the `au-slot` docs, it is here: [https://docs.aurelia.io/components/shadow-dom-and-slots#au-slot](https://docs.aurelia.io/components/shadow-dom-and-slots#au-slot). The docs describe various scenarios. In case, your cases are more involved, you can also refer the [tests](https://github.com/aurelia/aurelia/blob/master/packages/ __tests__ /src/3-runtime-html/au-slot.spec.tsx) written for `au-slot` that covers even more cases, than documented.

Happy migration! ✌

---

<div class="post-metadata">

**Author:** ![Haltesh](https://avatars.discourse-cdn.com/v4/letter/h/f0a364/32.png) [@Haltesh](https://discourse.aurelia.io/u/Haltesh)\
**Post date:** [January 20, 2025, 6:27am UTC](https://discourse.aurelia.io/t/au2-migration-replace-part/6328/3 "2025-01-20T06:27:07Z")

</div>

Thanks for the reply!

I’ve been reading the documentation on slotted content multiple times, yet I somehow completely missed the part in the binding scope section specifically dealing with grids 😅.

I did manage to get it working now, but I have to explicitly use `$host`, otherwise I seem to always get an undefined property.
