Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

Reference

Slots

A Slot is a high-level interface for developers to define and manage dynamic content insertion within drop-in components.

Context

The context is defined during implementation of a drop-in and can be used to pass data and functions to the slot.

Pre-built Methods

  • dictionary: The dictionary of the selected language.
  • replaceWith: A function to replace the slot’s content with a new HTML element.
  • appendChild: A function to append a new HTML element to the slot’s content.
  • prependChild: A function to prepend a new HTML element to the slot’s content.
  • appendSibling: A function to append a new HTML element after the slot’s content.
  • prependSibling: A function to prepend a new HTML element before the slot’s content.
  • getSlotElement: A function to get a slot element.
  • onChange: A function to listen to changes in the slot’s context.

Implementing a new slot

The <Slot /> component is used to define a slot in a container. It receives a name and a slot object with the following properties:

name

The name of the slot in PascalCase. string (required).

slotTag

The HTML tag to use for the slot’s wrapper element. This allows you to change the wrapper element from the default div to any valid HTML tag (e.g., ‘span’, ‘p’, ‘a’, etc.). When using specific tags like ‘a’, you can also provide their respective HTML attributes (e.g., ‘href’, ‘target’, etc.).

Example:

// Render with a span wrapper
<Slot name="MySlot" slotTag="span">
Inline content
</Slot>
// Render with an anchor wrapper
<Slot name="MySlot" slotTag="a" href="https://example.com" target="_blank">
Link content
</Slot>

contentTag

The HTML tag to use for wrapping dynamically inserted content within the slot. This is separate from the slot’s wrapper tag and allows you to control how dynamic content is structured. Defaults to ‘div’.

Example:

<Slot
name="MySlot"
slotTag="article" // The outer wrapper will be an article
contentTag="section" // Dynamic content will be wrapped in sections
slot={(ctx) => {
const elem = document.createElement('div');
elem.innerHTML = 'Dynamic content';
ctx.appendChild(elem); // This will be wrapped in a section tag
}}
/>

slot (required)

  • ctx: An object representing the context of the slot, including methods for manipulating the slot’s content.

The slot property, which is implemented as a promise function, provides developers with the flexibility to dynamically generate and manipulate content within slots. However, it’s important to note that this promise is render-blocking, meaning that the component will not render until the promise is resolved.

context

The context property in the Slot component lets developers pass extra information or functionality to customize how the slot behaves or interacts with the application. This information is accessible within the slot’s rendering logic, allowing for tailored slot behavior based on specific needs or application states.

render

The render property in the Slot component lets developers define how the content within the slot should be displayed and should be used when developers need fine-grained control over what content appears within the slot. It’s particularly useful when using custom slot methods (see Privates below) in scenarios where the content to be displayed within the slot is dynamic and may depend on properties passed to another component.

children

The children property in the Slot component represents the content that is passed directly within the opening and closing tags of the Slot component. It allows developers to include static content directly within the slot, which will be rendered as part of the slot’s contents. This property is useful for cases where the content within the slot is static or does not need to be dynamically generated by the slot.

// MyContainer.tsx (Drop-in)
import { HTMLAttributes } from 'preact/compat';
import { Container, Slot, SlotProps } from '@adobe-commerce/elsie/lib';
export interface MyContainerProps extends HTMLAttributes<HTMLDivElement> {
slots?: {
MyOpenSlot?: SlotProps<{
// MyOpenSlot Context
data: MyContainerData;
}>;
};
}
export const MyContainer: Container<MyContainerProps> = ({
slots,
children,
...props
}) => {
// ...
return (
<div {...props}>
<Slot name="MyOpenSlot" slot={slots?.MyOpenSlot} context={{ data }} />
</div>
);
};

 

// blocks/my-block.js (storefront)
provider.render(MyContainer, {
slots: {
MyOpenSlot: async (ctx) => {
// create a new HTML element
const element = document.createElement('div');
// set the innerHTML of the new element to the text from the context's data
element.innerHTML = ctx.data.text;
// append the new element to the slot's content
ctx.appendChild(element);
// ...or you could also use any of the other slot methods to manipulate the slot's content
// ctx.replaceWith(element);
// ctx.prependChild(element);
// ctx.appendSibling(element);
// ctx.prependSibling(element);
// to listen and react to changes in the slot's context (lifecycle)
ctx.onChange((next) => {
// update the innerHTML of the new element to the new text from the context's data
element.innerHTML = ctx.data.text;
});
},
},
});

Privates

The <Slot /> component has a private interface that serves as a mechanism for managing internal complexity and promoting clean, modular design within the Slot component or related components.

_registerMethod

The _registerMethod private function is used to register a method in the slot’s context which is particularly helpful in scenarios where dynamic behavior or interactions need to be incorporated into the Slot component.

Slot Methods also include the ability to modify the slot’s state or content based on external interactions or changes in application state.

_setProps

The _setProps private function within the Slot component is responsible for dynamically updating the properties of the slot. It allows developers to modify the slot’s state or content based on external interactions or changes in application state, triggering re-renders of the slot component with updated properties.

_htmlElementToVNode

The _htmlElementToVNode private function in the Slot component converts HTML elements into virtual DOM nodes (VNodes), enabling their integration into Preact components. This conversion facilitates the dynamic insertion of HTML content into slots while benefiting from Preact’s virtual DOM reconciliation and rendering.

// MyContainer.tsx (Drop-in)
<Slot
name="MyOpenSlot"
slot={slots?.MyOpenSlot}
context={{
// custom slot method
appendButton(callback) {
// use _registerMethod to register a method in the slot's context
this._registerMethod((...attrs) => {
// callback return the values provided by the storefront developer
const { text, ...buttonProps } = callback(...attrs);
const button = (
<Button type="button" {...buttonProps}>
{text}
</Button>
);
// use _setProps to update the slot's properties
this._setProps((prev: any) => ({
children: [...(prev.children || []), button],
}));
});
},
}}
render={(props) => {
// render the slot's content using props mutated by the slot's methods
return <Buttons>{props.children}</Buttons>;
}}
/>

 

// blocks/my-block.js (storefront)
provider.render(MyContainer, {
slots: {
// Available Slots
MyOpenSlot: (ctx) => {
ctx.appendButton: (next, state) => {
// use state to get the current state of the slot
const loading = state.get('loading');
return {
text: loading ? 'Loading' : 'Click me!',
onClick: async () => {
// use state to update the state of the slot
state.set('loading', true);
await doSomething().finally(() => {
state.set('loading', false);
});
},
};
},
},
},
});