Skip to main content
Jack Sleight .DEV
Alpine

Alpine x-node directive

Alpine's x-text and x-html directives allow you to set an element's text or HTML content, but what if you have a DOM node, either from the current page or one that you've created, and want to add that to an element with Alpine?

You could use innerHTML and x-html, but that may not be very efficient. Instead you can implement a custom directive that gives you the ability to add DOM nodes directly:

import Alpine from 'alpinejs'
 
Alpine.directive('node', (el, { modifiers, expression }) => {
let evaluate = Alpine.evaluateLater(el, expression)
Alpine.effect(() => {
evaluate(value => {
Alpine.mutateDom(() => {
if (value) {
const node = modifiers.includes('clone')
? value.cloneNode(true)
: value;
el.replaceChildren(node);
} else {
el.replaceChildren();
}
})
})
})
});
import Alpine from 'alpinejs'
 
Alpine.directive('node', (el, { modifiers, expression }) => {
let evaluate = Alpine.evaluateLater(el, expression)
Alpine.effect(() => {
evaluate(value => {
Alpine.mutateDom(() => {
if (value) {
const node = modifiers.includes('clone')
? value.cloneNode(true)
: value;
el.replaceChildren(node);
} else {
el.replaceChildren();
}
})
})
})
});

You can use x-node in your markup, it works in exactly the same way as x-text and x-html. If you want to add a clone of the node rather than the original you can use the clone modifier:

<div x-node="item"></div>
<div x-node.clone="item"></div>
<div x-node="item"></div>
<div x-node.clone="item"></div>
9th May 2022