In Nuxt we have access to the server and can control server side rendering. If I create a directive v-skip
that removes an element from a DOM tree but simply moves its children into its parent, for example:
<template>
<div class="parent">
<div class="remove-me" v-skip>
<p>child 1</p>
<div>
<p>nested child 1</p>
<p>nested child 2</p>
</div>
</div>
</div>
</template>
Becomes
<template>
<div class="parent">
<p>child 1</p>
<div>
<p>nested child 1</p>
<p>nested child 2</p>
</div>
</div>
</template>
This can be implemented like this and the end result works by producing the expected output, but it doesn’t run on the server. There’s a hydration mismatch of course because the <div class="remove-me">
is rendered on the server.
Now it‘s clear we don‘t have access to browser apis on the server, but Vue still has vNodes and has the ability to render html on the server.
<script setup>
const vSkip = {
created(el, binding, vNode) {
handleSkip(el)
}
}
function handleSkip(elementToRemove) {
const parent = elementToRemove.parentNode;
while (elementToRemove.firstChild) {
const child = elementToRemove.firstChild;
parent.insertBefore(child, elementToRemove);
}
parent.removeChild(elementToRemove);
}
</script>
<template>
<div class="parent">
<div class="remove-me" v-skip>
<p>child 1</p>
<div>
<p>nested child 1</p>
<p>nested child 2</p>
</div>
</div>
</div>
</template>