La API slot nos permite crear espacios dinámicos dentro de nuestros custom elements para insertar contenido personalizado de forma sencilla y flexible. Esto lo conseguimos usando únicamente el lenguaje de marcas, sin necesidad de complicarnos con atributos observados o cambios manuales en el DOM. El navegador se encarga automáticamente de sustituir el contenido de ciertos nodos dentro de la plantilla o del shadow DOM según el código que hayamos definido en nuestro custom element.
Por ejemplo, en lugar de tener un título fijo dentro de una etiqueta strong, podemos reemplazarlo por un elemento slot con un nombre específico, como titulo. Este slot actúa como un placeholder donde podemos soltar contenido personalizado. Así, dentro del custom element, podemos incluir un nodo con el atributo slot="titulo" que contendrá el texto que queremos mostrar, como un mensaje de error o cualquier otro contenido. El navegador enlaza automáticamente este nodo con el slot correspondiente, facilitando la inserción dinámica de contenido.
Además, podemos definir varios slots con diferentes nombres para organizar mejor el contenido. Por ejemplo, podemos tener un slot llamado contenido para el cuerpo principal y otro llamado titulo para el encabezado. Si no proporcionamos contenido para un slot, podemos definir un texto por defecto dentro de la etiqueta slot para que se muestre en su lugar. Esto nos permite manejar casos en los que no se pasa contenido personalizado, asegurando que siempre haya algo visible.
Un detalle importante es que el contenido que pongamos dentro del slot se clona tal cual, incluyendo las etiquetas HTML que usemos. Por eso, es recomendable usar elementos apropiados como span o div para evitar problemas de estilo o estructura. Si un slot no tiene nombre, el navegador insertará todo el contenido que no tenga asignado un slot específico, lo que facilita la composición de componentes anidados.
Esta capacidad de pasar contenido a través de slots mejora mucho la reutilización y composición de componentes web, ya que podemos insertar múltiples nodos o incluso texto escapado sin complicaciones. Además, podemos combinar esta técnica con atributos normales para manejar casos más simples, como un título que se pase directamente como atributo y se refleje en el shadow DOM mediante una función de renderizado.
Por último, es interesante aprovechar que los navegadores que no reconocen custom elements los tratan como elementos genéricos tipo div. Esto nos permite implementar una mejora progresiva (progressive enhancement), mostrando contenido básico para navegadores antiguos y enriqueciendo la experiencia en navegadores modernos que soportan shadow DOM y slots. Así, garantizamos compatibilidad y una mejor experiencia de usuario sin perder funcionalidad.
Un ejemplo básico de cómo definir un slot en un template de un custom element y pasarle contenido sería el siguiente:
<template id="mi-componente-template">
<style>
/* estilos del componente */
</style>
<h3><slot name="titulo">Error</slot></h3>
<p><slot name="contenido"></slot></p>
</template>
<script>
class MiComponente extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
const template = document.getElementById('mi-componente-template');
shadow.appendChild(template.content.cloneNode(true));
}
}
customElements.define('mi-componente', MiComponente);
</script>
<!-- Uso del componente -->
<mi-componente>
<span slot="titulo">Permiso denegado</span>
<span slot="contenido">No tienes acceso a esta sección.</span>
</mi-componente>
Con esta estructura, el navegador reemplaza automáticamente los slots con el contenido que le pasamos, o muestra el texto por defecto si no se proporciona nada. Esto simplifica mucho la creación de componentes web reutilizables y flexibles.