{"id":43413,"date":"2021-09-09T09:34:27","date_gmt":"2021-09-09T07:34:27","guid":{"rendered":"https:\/\/kinsta.com\/?p=98073"},"modified":"2025-02-07T15:15:10","modified_gmt":"2025-02-07T14:15:10","slug":"componentes-web","status":"publish","type":"post","link":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/","title":{"rendered":"Una Introducci\u00f3n Completa a los Componentes Web en 2026"},"content":{"rendered":"<p>Todos tenemos proyectos en los que preferir\u00edamos no trabajar. El c\u00f3digo se ha vuelto inmanejable, el alcance del proyecto ha evolucionado, se han aplicado correcciones r\u00e1pidas sobre otras correcciones y la estructura se ha derrumbado bajo su peso de c\u00f3digo espagueti. Codificar puede ser un asunto desordenado.<\/p>\n<p>Los proyectos se benefician del uso de m\u00f3dulos simples e independientes que tienen una \u00fanica responsabilidad. El c\u00f3digo modular est\u00e1 encapsulado, por lo que hay menos necesidad de preocuparse por la implementaci\u00f3n. Mientras sepas lo que producir\u00e1 un m\u00f3dulo cuando se le d\u00e9 un conjunto de entradas, no tendr\u00e1s que entender necesariamente <em>c\u00f3mo <\/em>has conseguido ese objetivo.<\/p>\n<p>Aplicar los conceptos modulares a un \u00fanico <a href=\"https:\/\/kinsta.com\/es\/blog\/mejor-lenguaje-de-programacion-para-aprender\/\">lenguaje de programaci\u00f3n<\/a> es sencillo, pero el desarrollo web requiere una mezcla variada de tecnolog\u00edas. <a href=\"https:\/\/kinsta.com\/es\/cuota-mercado-mundial-navegadores\/\">Los navegadores<\/a> analizan <a href=\"https:\/\/kinsta.com\/es\/blog\/html-vs-html5\/\">HTML<\/a>, CSS y JavaScript para representar el contenido, los estilos y la funcionalidad de la p\u00e1gina.<\/p>\n<p>No siempre se mezclan f\u00e1cilmente porque:<\/p>\n<ul>\n<li>El c\u00f3digo relacionado puede dividirse entre tres o m\u00e1s archivos, y<\/li>\n<li>Los estilos globales y los objetos JavaScript pueden interferir entre s\u00ed de forma inesperada.<\/li>\n<\/ul>\n<p>Estos problemas se suman a los que tienen los tiempos de ejecuci\u00f3n del lenguaje, los <a href=\"https:\/\/kinsta.com\/es\/blog\/bibliotecas-javascript\/\">frameworks<\/a>, las bases de datos y otras dependencias utilizadas en el servidor.<\/p>\n<h3>Consulta Nuestro <a href=\"https:\/\/www.youtube.com\/watch?v=hVxZ-te0kio\">Videotutorial<\/a> Sobre Componentes Web<\/h3>\n<kinsta-video src=\"https:\/\/www.youtube.com\/watch?v=hVxZ-te0kio\"><\/kinsta-video>\n<div><\/div><kinsta-auto-toc heading=\"Table of Contents\" exclude=\"last\" list-style=\"arrow\" selector=\"h2\" count-number=\"-1\"><\/kinsta-auto-toc>\n<h2>\u00bfQu\u00e9 son los componentes web?<\/h2>\n<p>Un Componente Web es una forma de crear un bloque de c\u00f3digo encapsulado y de responsabilidad \u00fanica que puede reutilizarse en cualquier p\u00e1gina.<\/p>\n<p>Considera la etiqueta HTML <code><strong>&lt;video&gt;<\/strong><\/code>. Dada una <a href=\"https:\/\/kinsta.com\/es\/blog\/que-es-una-url\/\">URL<\/a>, un espectador puede utilizar controles como reproducir, pausar, retroceder, avanzar y ajustar el volumen.<\/p>\n<p>Se proporciona el estilo y la funcionalidad, aunque se pueden hacer modificaciones utilizando varios atributos y llamadas a la API de JavaScript. Se puede colocar cualquier n\u00famero de elementos <code><strong>&lt;video&gt; <\/strong><\/code>dentro de otras etiquetas, y no entrar\u00e1n en conflicto.<\/p>\n<p>\u00bfY si necesitas tu propia funcionalidad personalizada? Por ejemplo, un elemento que muestre el n\u00famero de palabras en la p\u00e1gina? No hay etiqueta HTML <code><strong>&lt;wordcount&gt;<\/strong><\/code> (todav\u00eda).<\/p>\n<p>Frameworks como <a href=\"https:\/\/kinsta.com\/es\/blog\/bibliotecas-javascript\/#reactjs\">React<\/a> y <a href=\"https:\/\/kinsta.com\/es\/blog\/vue-js\/\">Vue.js<\/a> permiten a los desarrolladores crear componentes web en los que el contenido, el estilo y la funcionalidad se pueden definir en un \u00fanico archivo JavaScript. Estos resuelven muchos problemas de programaci\u00f3n complejos, pero ten en cuenta que:<\/p>\n<ul>\n<li>Debes aprender a utilizar ese marco y actualizar tu c\u00f3digo a medida que evoluciona.<\/li>\n<li>Un componente escrito para un marco de trabajo rara vez es compatible con otro.<\/li>\n<li>La popularidad de los frameworks aumenta y disminuye. Se volver\u00e1 dependiente de los caprichos y prioridades del equipo de desarrollo y de los usuarios.<\/li>\n<li>Los Componentes Web est\u00e1ndar pueden a\u00f1adir funcionalidades al navegador, que son dif\u00edciles de conseguir solo con JavaScript (como el Shadow DOM).<\/li>\n<\/ul>\n<p>Afortunadamente, los conceptos populares introducidos en librer\u00edas y frameworks suelen llegar a los est\u00e1ndares web. Ha tardado alg\u00fan tiempo, pero los Web Components han llegado.<\/p>\n\n<h2>Breve historia de los componentes web<\/h2>\n<p>Despu\u00e9s de muchos comienzos falsos de proveedores espec\u00edficos, el concepto de Componentes Web est\u00e1ndar fue introducido por primera vez por <a href=\"https:\/\/fronteers.nl\/congres\/2011\/sessions\/web-components-and-model-driven-views-alex-russell\">Alex Russell en la Conferencia Fronteers en 2011<\/a>. La <a href=\"https:\/\/github.com\/Polymer\/polymer\">biblioteca Polymer<\/a> de Google (un polyfill basado en las propuestas actuales) lleg\u00f3 dos a\u00f1os despu\u00e9s, pero las primeras implementaciones no aparecieron en Chrome y Safari hasta 2016.<\/p>\n<p>Los proveedores de navegadores se tomaron su tiempo para negociar los detalles, pero los Componentes Web se a\u00f1adieron a Firefox en 2018 y a Edge en 2020 (cuando Microsoft cambi\u00f3 al motor Chromium).<\/p>\n<p>Es comprensible que pocos desarrolladores hayan querido o podido adoptar los Web Components, pero por fin hemos alcanzado un buen nivel de soporte de los navegadores con APIs estables. No todo es perfecto, pero son una alternativa cada vez m\u00e1s viable a los componentes basados en frameworks.<\/p>\n<p>Incluso si no est\u00e1s dispuesto a deshacerte de tu favorito todav\u00eda, los Web Components son compatibles con <em>todos los <\/em>frameworks, y las APIs recibir\u00e1n soporte durante a\u00f1os.<\/p>\n<p>Los repositorios de Componentes Web pre-construidos est\u00e1n disponibles para que todos puedan echar un vistazo:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.webcomponents.org\/\">WebComponents.org<\/a><\/li>\n<li><a href=\"https:\/\/component.gallery\/\">The Component Gallery<\/a><\/li>\n<li><a href=\"https:\/\/genericcomponents.netlify.app\/\">generic-components<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/mdn\/web-components-examples\">web-components-examples<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/davatron5000\/awesome-standalones\">awesome-standalones<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/scottaohara\/accessible_components\">accessible_components<\/a><\/li>\n<li><a href=\"https:\/\/kickstand-ui.com\/\">Kickstand UI<\/a><\/li>\n<\/ul>\n<p>&#8230; \u00a1pero escribir tu propio c\u00f3digo es m\u00e1s divertido!<\/p>\n<p>Este tutorial proporciona una completa introducci\u00f3n a los Componentes Web escritos sin un framework de JavaScript. Aprender\u00e1s qu\u00e9 son y c\u00f3mo adaptarlos a tus proyectos web. Necesitar\u00e1s algunos conocimientos de <a href=\"https:\/\/kinsta.com\/es\/blog\/html-vs-html5\/\">HTML5<\/a>, CSS y JavaScript.<\/p>\n<h2>Introducci\u00f3n a los componentes web<\/h2>\n<p>Los Web Components son elementos HTML personalizados como <code><strong>&lt;hello-world&gt;&lt;\/hello-world&gt;<\/strong><\/code>. El nombre debe contener un gui\u00f3n para no chocar nunca con los elementos admitidos oficialmente en la especificaci\u00f3n HTML.<\/p>\n<p>Debes definir una clase ES2015 para controlar el elemento. Puede tener cualquier nombre, pero HelloWorld es una pr\u00e1ctica com\u00fan. Debe extender la <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/HTMLElement\">interfaz HTMLElement<\/a>, que representa las propiedades y m\u00e9todos por defecto de todo elemento HTML.<\/p>\n<p><strong>Nota: <\/strong><a href=\"https:\/\/kinsta.com\/es\/blog\/navegador-mas-seguro\/#3-firefox\">Firefox<\/a> permite extender elementos HTML espec\u00edficos como HTMLParagraphElement, HTMLImageElement o HTMLButtonElement. Esto no est\u00e1 soportado en otros navegadores y no permite crear un Shadow DOM.<\/p>\n<p>Para hacer algo \u00fatil, la clase requiere un m\u00e9todo llamado <strong>connectedCallback() <\/strong>que se invoca cuando el elemento se a\u00f1ade a un documento:<\/p>\n<pre><code class=\"language-html\">class HelloWorld extends HTMLElement {\n\n  \/\/ connect component\n  connectedCallback() {\n    this.textContent = 'Hello World!';\n  }\n\n}\n<\/code><\/pre>\n<p>En este ejemplo, el texto del elemento se establece como \u00abHola Mundo\u00bb.<\/p>\n<p>La clase debe ser registrada en el <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/CustomElementRegistry\">CustomElementRegistry<\/a> para definirla como manejadora de un elemento espec\u00edfico:<\/p>\n<pre><code class=\"language-html\">customElements.define( 'hello-world', HelloWorld );\n<\/code><\/pre>\n<p>El navegador asocia ahora el elemento <code><strong>&lt;hello-world&gt;<\/strong><\/code> con tu clase <strong>HelloWorld <\/strong>cuando se carga tu JavaScript (por ejemplo, <code><b>&lt;script type=\"module\" src=\".\/helloworld.js\"&gt;&lt;\/script&gt;<\/b><\/code>).<\/p>\n<p>Ya tienes un elemento personalizado.<\/p>\n<p><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" title=\"&lt;hello-world&gt; component\" src=\"https:\/\/codepen.io\/craigbuckler\/embed\/preview\/WNpaxPN?default-tabs=js%2Cresult&#038;height=300&#038;host=https%3A%2F%2Fcodepen.io&#038;slug-hash=WNpaxPN#?secret=fXyFBzGnEb\" data-secret=\"fXyFBzGnEb\" scrolling=\"no\" frameborder=\"0\" height=\"300\"><\/iframe><\/p>\n<p><a href=\"https:\/\/codepen.io\/craigbuckler\/pen\/WNpaxPN\">Demostraci\u00f3n de CodePen<\/a><\/p>\n<p>Este componente puede ser estilizado en CSS como cualquier otro elemento:<\/p>\n<pre><code class=\"language-css\">hello-world {\n  font-weight: bold;\n  color: red;\n}\n<\/code><\/pre>\n<h3>A\u00f1adir atributos<\/h3>\n<p>Este componente no es beneficioso, ya que el mismo texto se emite independientemente. Como cualquier otro elemento, podemos a\u00f1adir atributos HTML:<\/p>\n<pre><code class=\"language-html\">&lt;hello-world name=\"Craig\"&gt;&lt;\/hello-world&gt;\n<\/code><\/pre>\n<p>Esto podr\u00eda anular el texto para que se muestre \u00ab\u00a1Hola Craig!\u00bb. Para lograr esto, puedes a\u00f1adir una funci\u00f3n <strong>constructora() <\/strong>a la clase <strong>HelloWorld<\/strong>, que se ejecuta cuando se crea cada objeto. Debe:<\/p>\n<ol>\n<li>llamar al m\u00e9todo <strong>super() <\/strong>para inicializar el HTMLElement padre, y<\/li>\n<li>hacer otras inicializaciones. En este caso, definiremos una propiedad <strong>name <\/strong>que se establece por defecto en \u00abWorld\u00bb:<\/li>\n<\/ol>\n<pre><code class=\"language-js\">class HelloWorld extends HTMLElement {\n\n  constructor() {\n    super();\n    this.name = 'World';\n  }\n\n  \/\/ more code...\n<\/code><\/pre>\n<p>Tu componente solo se preocupa por el atributo <strong>name<\/strong>. Una propiedad est\u00e1tica <strong>observedAttributes() <\/strong>debe devolver un array de propiedades a observar:<\/p>\n<pre><code class=\"language-js\">\/\/ component attributes\nstatic get observedAttributes() {\n  return ['name'];\n}\n<\/code><\/pre>\n<p>Un m\u00e9todo <strong>attributeChangedCallback() <\/strong>es llamado cuando un atributo es definido en el HTML o cambiado usando JavaScript. Se le pasa el nombre de la propiedad, el valor antiguo y el nuevo valor:<\/p>\n<pre><code class=\"language-js\">\/\/ attribute change\nattributeChangedCallback(property, oldValue, newValue) {\n\n  if (oldValue === newValue) return;\n  this[ property ] = newValue;\n\n}\n<\/code><\/pre>\n<p>En este ejemplo, solo se actualizar\u00eda la propiedad <strong>nombre<\/strong>, pero podr\u00eda a\u00f1adir otras propiedades si fuera necesario.<\/p>\n<p>Por \u00faltimo, hay que modificar el mensaje en el m\u00e9todo <strong>connectedCallback()<\/strong>:<\/p>\n<pre><code class=\"language-js\">\/\/ connect component\nconnectedCallback() {\n\n  this.textContent = `Hello ${ this.name }!`;\n\n}\n<\/code><\/pre>\n<p><a href=\"https:\/\/codepen.io\/craigbuckler\/pen\/BaWqLOK\">Demostraci\u00f3n de CodePen<\/a><\/p>\n<h3>M\u00e9todos del ciclo de vida<\/h3>\n<p>El navegador llama autom\u00e1ticamente a seis m\u00e9todos a lo largo del ciclo de vida del estado del Componente Web. La lista completa se proporciona aqu\u00ed, aunque ya has visto los cuatro primeros en los ejemplos anteriores:<\/p>\n<h4>constructor()<\/h4>\n<p>Se llama cuando el componente se inicializa por primera vez. Debe llamar a <strong>super() <\/strong>y puede establecer cualquier valor por defecto o realizar otros procesos de pre-renderizaci\u00f3n.<\/p>\n<h4>static observedAttributes()<\/h4>\n<p>Devuelve un array de atributos que el navegador observar\u00e1.<\/p>\n<h4>attributeChangedCallback(propertyName,<b> oldValue, newValue)<\/b><\/h4>\n<p>Se llama cada vez que se modifica un atributo observado. Los definidos en HTML se pasan inmediatamente, pero JavaScript puede modificarlos:<\/p>\n<pre><code class=\"language-js\">document.querySelector('hello-world').setAttribute('name', 'Everyone');\n<\/code><\/pre>\n<p>Es posible que el m\u00e9todo tenga que volver a renderizar cuando esto ocurra.<\/p>\n<h4>connectedCallback()<\/h4>\n<p>Esta funci\u00f3n es llamada cuando el Componente Web es anexado a un Modelo de Objeto de Documento. Debe ejecutar cualquier renderizaci\u00f3n requerida.<\/p>\n<h4>disconnectedCallback()<\/h4>\n<p>Se llama cuando el Componente Web es eliminado de un Modelo de Objeto de Documento. Esto puede ser \u00fatil si necesitas hacer una limpieza, como eliminar el estado almacenado o abortar <a href=\"https:\/\/kinsta.com\/es\/blog\/admin-ajax\/\">las peticiones Ajax<\/a>.<\/p>\n<h4>adoptedCallback()<\/h4>\n<p>Esta funci\u00f3n se llama cuando un componente web se mueve de un documento a otro. Es posible que encuentres un uso para esto, aunque me ha costado pensar en alg\u00fan caso.<\/p>\n<h2>C\u00f3mo interact\u00faan los componentes web con otros elementos<\/h2>\n<p>Los Componentes Web ofrecen una funcionalidad \u00fanica que no encontrar\u00e1s en los frameworks de JavaScript.<\/p>\n<h3>El Shadow DOM<\/h3>\n<p>Aunque el componente web que hemos construido arriba funciona, no es inmune a las interferencias externas, y CSS o JavaScript podr\u00edan modificarlo. Del mismo modo, los estilos que definas para tu componente podr\u00edan filtrarse y afectar a otros.<\/p>\n<p>El Shadow DOM resuelve este problema de encapsulaci\u00f3n adjuntando un DOM separado al Web Component con:<\/p>\n<pre><code class=\"language-js\">const shadow = this.attachShadow({ mode: 'closed' });\n<\/code><\/pre>\n<p>El modo puede ser:<\/p>\n<ol>\n<li><strong>\u00abopen\u00bb <\/strong>&#8211; JavaScript en la p\u00e1gina exterior puede acceder al DOM de la sombra (usando <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/Element\/shadowRoot\">Element.shadowRoot<\/a>), o<\/li>\n<li><strong>\u00abclosed\u00bb <\/strong>&#8211; solo se puede acceder al Shadow DOM dentro del Web Component.<\/li>\n<\/ol>\n<p>El Shadow DOM puede ser manipulado como cualquier otro elemento del DOM:<\/p>\n<pre><code class=\"language-js\">connectedCallback() {\n\n  const shadow = this.attachShadow({ mode: 'closed' });\n\n  shadow.innerHTML = `\n    &lt;style&gt;\n      p {\n        text-align: center;\n        font-weight: normal;\n        padding: 1em;\n        margin: 0 0 2em 0;\n        background-color: #eee;\n        border: 1px solid #666;\n      }\n    &lt;\/style&gt;\n\n    &lt;p&gt;Hello ${ this.name }!&lt;\/p&gt;`;\n\n}\n<\/code><\/pre>\n<p>El componente ahora renderiza el texto \u00abHola\u00bb dentro de un elemento <code><strong>&lt;p&gt;<\/strong><\/code> y lo estiliza. No puede ser modificado por JavaScript o CSS fuera del componente, aunque algunos estilos como la <a href=\"https:\/\/kinsta.com\/es\/blog\/html-fuentes\/\">fuente<\/a> y el color se heredan de la p\u00e1gina porque no fueron definidos expl\u00edcitamente.<\/p>\n<p><a href=\"https:\/\/codepen.io\/craigbuckler\/pen\/rNyqyJJ\">Demostraci\u00f3n de CodePen<\/a><\/p>\n<p>Los estilos asignados a este componente web no pueden afectar a otros p\u00e1rrafos de la p\u00e1gina ni a otros componentes de <code><strong>&lt;hello-world&gt;<\/strong><\/code>.<\/p>\n<p>Ten en cuenta que el selector CSS<code> :host<\/code> puede estilizar el elemento exterior <strong><code>&lt;hello-world&gt;<\/code> <\/strong>desde el componente web:<\/p>\n<pre><code class=\"language-css\">:host {\n  transform: rotate(180deg);\n}\n<\/code><\/pre>\n<p>Tambi\u00e9n puedes establecer los estilos que se aplicar\u00e1n cuando el elemento utilice una clase espec\u00edfica, por ejemplo, <code><b>&lt;hello-world class=\"rotate90\"&gt;<\/b><\/code>:<\/p>\n<pre><code class=\"language-css\">:host(.rotate90) {\n  transform: rotate(90deg);\n}\n<\/code><\/pre>\n<h3>Plantillas HTML<\/h3>\n<p>Definir el HTML dentro de un script puede resultar poco pr\u00e1ctico para componentes web m\u00e1s complejos. Una plantilla te permite definir un trozo de HTML en tu p\u00e1gina que tu Componente Web puede utilizar. Esto tiene varias ventajas:<\/p>\n<ol>\n<li>Puedes modificar el c\u00f3digo HTML sin tener que reescribir las cadenas dentro de su JavaScript.<\/li>\n<li>Los componentes pueden ser personalizados sin tener que crear clases JavaScript separadas para cada tipo.<\/li>\n<li>Es m\u00e1s f\u00e1cil definir el HTML en HTML &#8211; y puede ser modificado en el servidor o en el cliente antes de que el componente se renderice.<\/li>\n<\/ol>\n<p>Las plantillas se definen en una etiqueta <code><strong>&lt;template&gt;<\/strong><\/code>, y es pr\u00e1ctico asignar un ID para poder referenciarlo dentro de la clase del componente. Este ejemplo tres p\u00e1rrafos para mostrar el mensaje \u00abHola\u00bb:<\/p>\n<pre><code class=\"language-html\">&lt;template id=\"hello-world\"&gt;\n\n  &lt;style&gt;\n    p {\n      text-align: center;\n      font-weight: normal;\n      padding: 0.5em;\n      margin: 1px 0;\n      background-color: #eee;\n      border: 1px solid #666;\n    }\n  &lt;\/style&gt;\n\n  &lt;p class=\"hw-text\"&gt;&lt;\/p&gt;\n  &lt;p class=\"hw-text\"&gt;&lt;\/p&gt;\n  &lt;p class=\"hw-text\"&gt;&lt;\/p&gt;\n\n&lt;\/template&gt;\n<\/code><\/pre>\n<p>La clase Web Component puede acceder a esta plantilla, obtener su contenido y <a href=\"https:\/\/kinsta.com\/es\/blog\/clonar-sitio-wordpress\/\">clonar<\/a> los elementos para asegurarse de que est\u00e1 creando un fragmento de DOM \u00fanico en todos los lugares donde se utiliza:<\/p>\n<pre><code class=\"language-js\">const template = document.getElementById('hello-world').content.cloneNode(true);<\/code><\/pre>\n<p>El DOM puede modificarse y a\u00f1adirse directamente al Shadow DOM:<\/p>\n<pre><code class=\"language-js\">connectedCallback() {\n\n  const\n\n    shadow = this.attachShadow({ mode: 'closed' }),\n    template = document.getElementById('hello-world').content.cloneNode(true),\n    hwMsg = `Hello ${ this.name }`;\n\n  Array.from( template.querySelectorAll('.hw-text') )\n    .forEach( n =&gt; n.textContent = hwMsg );\n\n  shadow.append( template );\n\n}\n<\/code><\/pre>\n<p><a href=\"https:\/\/codepen.io\/craigbuckler\/pen\/QWpZvdQ\">Demostraci\u00f3n de CodePen<\/a><\/p>\n<h3>Ranuras para plantillas<\/h3>\n<p>Las ranuras te permiten personalizar una plantilla. Supongamos que quieres utilizar tu componente web <code><strong>&lt;hello-world&gt;<\/strong><\/code> pero colocar el mensaje dentro de un encabezado <strong>&lt;h1&gt; <\/strong>en el DOM de la sombra. Podr\u00edas escribir este c\u00f3digo:<\/p>\n<pre><code class=\"language-html\">&lt;hello-world name=\"Craig\"&gt;\n\n  &lt;h1 slot=\"msgtext\"&gt;Hello Default!&lt;\/h1&gt;\n\n&lt;\/hello-world&gt;\n<\/code><\/pre>\n<p>(Observa el atributo de <strong>slot<\/strong>).<\/p>\n<p>Opcionalmente podr\u00edas querer a\u00f1adir otros elementos como otro p\u00e1rrafo:<\/p>\n<pre><code class=\"language-html\">&lt;hello-world name=\"Craig\"&gt;\n\n  &lt;h1 slot=\"msgtext\"&gt;Hello Default!&lt;\/h1&gt;\n  &lt;p&gt;This text will become part of the component.&lt;\/p&gt;\n\n&lt;\/hello-world&gt;\n<\/code><\/pre>\n<p>Las ranuras ahora pueden ser implementadas dentro de su plantilla:<\/p>\n<pre><code class=\"language-html\">&lt;template id=\"hello-world\"&gt;\n\n  &lt;slot name=\"msgtext\" class=\"hw-text\"&gt;&lt;\/slot&gt;\n\n  &lt;slot&gt;&lt;\/slot&gt;\n\n&lt;\/template&gt;\n<\/code><\/pre>\n<p>Un atributo de ranura de elemento establecido como \u00abmsgtext\u00bb (el <code><strong>&lt;h1&gt;<\/strong><\/code> ) se inserta en el punto donde hay un <code><strong>&lt;slot&gt;<\/strong><\/code> llamado \u00abmsgtext\u00bb. El <code><strong>&lt;p&gt;<\/strong><\/code> no tiene un nombre de ranura asignado, pero se utiliza en el siguiente <code><strong>&lt;slot&gt;<\/strong><\/code> sin nombre disponible. En efecto, la plantilla se convierte en:<\/p>\n<pre><code class=\"language-html\">&lt;template id=\"hello-world\"&gt;\n\n  &lt;slot name=\"msgtext\" class=\"hw-text\"&gt;\n    &lt;h1 slot=\"msgtext\"&gt;Hello Default!&lt;\/h1&gt;\n  &lt;\/slot&gt;\n\n  &lt;slot&gt;\n    &lt;p&gt;This text will become part of the component.&lt;\/p&gt;\n  &lt;\/slot&gt;\n\n&lt;\/template&gt;\n<\/code><\/pre>\n<p>En realidad no es tan sencillo. Un elemento <code><strong>&lt;slot&gt;<\/strong><\/code> en el Shadow DOM apunta a los elementos insertados. Solo se puede acceder a ellos localizando un <code><strong>&lt;slot&gt;<\/strong><\/code> y luego utilizando el <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/HTMLSlotElement\/assignedNodes\">m\u00e9todo .assignedNodes()<\/a> para devolver un array de hijos internos. El m\u00e9todo <strong>connectedCallback() <\/strong>actualizado:<\/p>\n<pre><code class=\"language-js\">connectedCallback() {\n\n  const\n    shadow = this.attachShadow({ mode: 'closed' }),\n    hwMsg = `Hello ${ this.name }`;\n\n  \/\/ append shadow DOM\n  shadow.append(\n    document.getElementById('hello-world').content.cloneNode(true)\n  );\n\n  \/\/ find all slots with a hw-text class\n  Array.from( shadow.querySelectorAll('slot.hw-text') )\n\n    \/\/ update first assignedNode in slot\n    .forEach( n =&gt; n.assignedNodes()[0].textContent = hwMsg );\n\n}\n<\/code><\/pre>\n<p><a href=\"https:\/\/codepen.io\/craigbuckler\/pen\/gOmBBvm\">Demostraci\u00f3n de CodePen<\/a><\/p>\n<p>Adem\u00e1s, no se puede aplicar estilo directamente a los elementos insertados, aunque s\u00ed se puede apuntar a ranuras espec\u00edficas dentro de su componente web:<\/p>\n<pre><code class=\"language-html\">&lt;template id=\"hello-world\"&gt;\n\n  &lt;style&gt;\n    slot[name=\"msgtext\"] { color: green; }\n  &lt;\/style&gt;\n\n  &lt;slot name=\"msgtext\" class=\"hw-text\"&gt;&lt;\/slot&gt;\n  &lt;slot&gt;&lt;\/slot&gt;\n\n&lt;\/template&gt;\n<\/code><\/pre>\n<p>Las ranuras de <a href=\"https:\/\/kinsta.com\/es\/blog\/wordpress-jerarquia-plantillas\/\">las plantillas<\/a> son un poco inusuales, pero una de las ventajas es que su contenido se mostrar\u00e1 si el JavaScript no se ejecuta. Este c\u00f3digo muestra un encabezado y un p\u00e1rrafo por defecto que s\u00f3lo se reemplazan cuando la clase Web Component se ejecuta con \u00e9xito:<\/p>\n<pre><code class=\"language-html\">&lt;hello-world name=\"Craig\"&gt;\n\n  &lt;h1 slot=\"msgtext\"&gt;Hello Default!&lt;\/h1&gt;\n  &lt;p&gt;This text will become part of the component.&lt;\/p&gt;\n\n&lt;\/hello-world&gt;\n<\/code><\/pre>\n<p>Por lo tanto, podr\u00edas implementar alguna forma de mejora progresiva, aunque solo sea un mensaje de \u00abNecesitas JavaScript\u00bb.<\/p>\n<h3>El Shadow DOM declarativo<\/h3>\n<p>Los ejemplos anteriores construyen un Shadow DOM utilizando JavaScript. Esa sigue siendo la \u00fanica opci\u00f3n, pero se est\u00e1 desarrollando un Shadow DOM declarativo experimental para <a href=\"https:\/\/kinsta.com\/es\/blog\/mejores-extensiones-chrome\/\">Chrome<\/a>. Esto permite el renderizado del lado del servidor y evita cualquier cambio de dise\u00f1o o destellos de contenido sin estilo.<\/p>\n<p>El siguiente c\u00f3digo es detectado por el parser HTML, que crea un Shadow DOM id\u00e9ntico al que creaste en la \u00faltima secci\u00f3n (tendr\u00edas que actualizar el mensaje seg\u00fan sea necesario):<\/p>\n<pre><code class=\"language-html\">&lt;hello-world name=\"Craig\"&gt;\n\n  &lt;template shadowroot=\"closed\"&gt;\n    &lt;slot name=\"msgtext\" class=\"hw-text\"&gt;&lt;\/slot&gt;\n    &lt;slot&gt;&lt;\/slot&gt;\n  &lt;\/template&gt;\n\n  &lt;h1 slot=\"msgtext\"&gt;Hello Default!&lt;\/h1&gt;\n  &lt;p&gt;This text will become part of the component.&lt;\/p&gt;\n\n&lt;\/hello-world&gt;<\/code><\/pre>\n<p>La funci\u00f3n no est\u00e1 disponible en ning\u00fan navegador, y no hay garant\u00eda de que llegue a Firefox o Safari. Puedes <a href=\"https:\/\/web.dev\/declarative-shadow-dom\/\">encontrar m\u00e1s informaci\u00f3n sobre el Shadow DOM declarativo,<\/a> y un polyfill es sencillo, pero ten en cuenta que la implementaci\u00f3n podr\u00eda cambiar.<\/p>\n<h3>Eventos de Shadow DOM<\/h3>\n<p>Tu Componente Web puede adjuntar eventos a cualquier elemento en el Shadow DOM como lo har\u00edas en el DOM de la p\u00e1gina, como por ejemplo escuchar los eventos de clic en todos los hijos internos:<\/p>\n<pre><code class=\"language-js\">shadow.addEventListener('click', e =&gt; {\n\n  \/\/ do something\n\n});\n<\/code><\/pre>\n<p>A menos que se <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/Event\/stopPropagation\">detenga la propagaci\u00f3n<\/a>, el evento se expandir\u00e1 en el DOM de la p\u00e1gina, pero el evento ser\u00e1 reorientado. Por lo tanto, parece venir de su elemento personalizado en lugar de elementos dentro de \u00e9l.<\/p>\n<h2>Uso de componentes web en otros frameworks<\/h2>\n<p>Cualquier Componente Web que crees funcionar\u00e1 en todos los <a href=\"https:\/\/kinsta.com\/es\/blog\/bibliotecas-javascript\/#the-most-popular-javascript-frameworks\">frameworks de JavaScript<\/a>. Ninguno de ellos conoce o se preocupa por los elementos HTML &#8211; tu componente <code><strong>&lt;hello-world&gt;<\/strong><\/code> ser\u00e1 tratado de forma id\u00e9ntica a un <code><strong>&lt;div&gt;<\/strong><\/code> y colocado en el DOM donde se activar\u00e1 la clase.<\/p>\n<p><a href=\"https:\/\/custom-elements-everywhere.com\/\">custom-elements-everywhere.com<\/a> proporciona una lista de frameworks y notas de Web Component. La mayor\u00eda son totalmente compatibles, aunque React.js tiene algunos problemas. Es posible utilizar <code><strong>&lt;hello-world&gt;<\/strong><\/code> en JSX:<\/p>\n<pre><code class=\"language-js\">import React from 'react';\nimport ReactDOM from 'react-dom';\nimport from '.\/hello-world.js';\n\nfunction MyPage() {\n\n  return (\n    &lt;&gt;\n      &lt;hello-world name=\"Craig\"&gt;&lt;\/hello-world&gt; \n    &lt;\/&gt;\n  );\n\n}\n\nReactDOM.render(&lt;MyPage \/&gt;, document.getElementById('root'));\n<\/code><\/pre>\n<p>&#8230;pero:<\/p>\n<ul>\n<li>React solo puede pasar tipos de datos primitivos a los atributos HTML (no arrays u objetos)<\/li>\n<li>React no puede escuchar los eventos de Web Component, por lo que debes adjuntar manualmente tus propios manejadores.<\/li>\n<\/ul>\n<h2>Cr\u00edticas y problemas de los componentes web<\/h2>\n<p>Los componentes web han mejorado mucho, pero algunos aspectos pueden ser dif\u00edciles de gestionar.<\/p>\n<h3>Dificultades de estilizaci\u00f3n<\/h3>\n<p>El estilo de los Components Web plantea algunos retos, sobre todo si se quiere anular los estilos de alcance. Hay muchas soluciones:<\/p>\n<ol>\n<li><strong>Evita utilizar el Shadow DOM. <\/strong>Podr\u00edas a\u00f1adir contenido directamente a tu elemento personalizado, aunque cualquier otro JavaScript podr\u00eda cambiarlo accidental o maliciosamente.<\/li>\n<li><strong>Utiliza las clases <\/strong><code><strong>:host<\/strong><\/code>. Como vimos anteriormente, el <a href=\"https:\/\/kinsta.com\/es\/blog\/ruta-de-visualizacion-critica\/#optimize-css\">CSS de \u00e1mbito<\/a> puedes aplicar estilos espec\u00edficos cuando se aplica una clase al elemento personalizado.<\/li>\n<li><strong>Comprueba las propiedades personalizadas (variables) de CSS. <\/strong>Las propiedades personalizadas se trasladan en cascada a los Web Components, por lo que, si tu elemento utiliza <code><strong>var(--my-color)<\/strong><\/code>, puedes establecer <code><strong>--my-color<\/strong><\/code> en un contenedor externo (como <code><strong>:root<\/strong><\/code>), y se utilizar\u00e1.<\/li>\n<li><strong>Aprovecha las partes de sombra. <\/strong>El nuevo <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/CSS\/::part\">selector ::part()<\/a> puede aplicar estilo a un componente interior que tenga un atributo part, es decir, <code><strong>&lt;h1 part=\"heading\"&gt;<\/strong><\/code> dentro de un componente <code><strong>&lt;hello-world&gt;<\/strong><\/code> puede aplicarse estilo con el selector <code><strong>hello-world::part(heading)<\/strong><\/code>.<\/li>\n<li><strong>Pasa una cadena de estilos. <\/strong>Puedes pasarlos como un atributo para aplicarlos dentro de un bloque <code><strong>&lt; style&gt;<\/strong><\/code>.<\/li>\n<\/ol>\n<p>Ninguno es ideal, y tendr\u00e1s que planificar cuidadosamente la forma en que otros usuarios pueden personalizar sus componente web.<\/p>\n<h3>Entradas ignoradas<\/h3>\n<p>Cualquier campo <code><b>&lt;input&gt;<\/b><\/code>, <code><b>&lt;textarea&gt;<\/b><\/code>, o <code><b>&lt;select&gt;<\/b><\/code> en su Shadow DOM no se asocia autom\u00e1ticamente dentro del formulario que lo contiene. Los primeros usuarios de Web Component a\u00f1ad\u00edan campos ocultos al DOM de la p\u00e1gina o utilizaban la <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/FormData\">interfaz FormData<\/a> para actualizar los valores. Ninguno de los dos es particularmente pr\u00e1ctico y rompe la encapsulaci\u00f3n de Web Component.<\/p>\n<p>La nueva interfaz ElementInternals permite que un componente web <a href=\"https:\/\/kinsta.com\/es\/blog\/wordpress-hooks\/\">se enganche a<\/a> los formularios para poder definir valores y validez personalizados. Est\u00e1 implementado en Chrome, pero hay un <a href=\"https:\/\/www.npmjs.com\/package\/element-internals-polyfill\">polyfill disponible<\/a> para otros navegadores.<\/p>\n<p>Para demostrarlo, crear\u00e1s un componente b\u00e1sico <code><b>&lt;input-age name=\"your-age\"&gt;&lt;\/input-age&gt;<\/b><\/code> . La clase debe tener un valor est\u00e1tico <strong>formAssociated <\/strong>establecido como true y, opcionalmente, un m\u00e9todo <strong>formAssociatedCallback() <\/strong>puede ser llamado cuando el formulario exterior se asocia:<\/p>\n<pre><code class=\"language-js\">\/\/ &lt;input-age&gt; web component\nclass InputAge extends HTMLElement {\n\n  static formAssociated = true;\n\n  formAssociatedCallback(form) {\n    console.log('form associated:', form.id);\n  }\n<\/code><\/pre>\n<p>El constructor debe ejecutar ahora el m\u00e9todo <strong>attachInternals()<\/strong>, que permite al componente comunicarse con el formulario y con otro <a href=\"https:\/\/kinsta.com\/es\/blog\/que-es-javascript\/\">c\u00f3digo JavaScript<\/a> que quiera inspeccionar el valor o la validaci\u00f3n:<\/p>\n<pre><code class=\"language-js\">  constructor() {\n\n    super();\n    this.internals = this.attachInternals();\n    this.setValue('');\n\n  }\n\n  \/\/ set form value\n\n  setValue(v) {\n\n    this.value = v;\n\n    this.internals.setFormValue(v);\n\n  }\n<\/code><\/pre>\n<p>El m\u00e9todo <strong>setFormValue() <\/strong>de ElementInternal establece el valor del elemento para el formulario padre inicializado con una cadena vac\u00eda aqu\u00ed (tambi\u00e9n se le puede pasar un objeto FormData con m\u00faltiples pares nombre\/valor). Otras propiedades y m\u00e9todos incluyen:<\/p>\n<ul>\n<li><strong>form<\/strong>: el formulario principal<\/li>\n<li><strong>labels<\/strong>: una matriz de elementos que etiquetan el componente<\/li>\n<li>Opciones de <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/Constraint_validation\">la API de validaci\u00f3n de restricciones<\/a> como willValidate, checkValidity y validationMessage<\/li>\n<\/ul>\n<p>El m\u00e9todo <strong>connectedCallback() <\/strong>crea un Shadow <a href=\"https:\/\/kinsta.com\/es\/blog\/ruta-de-visualizacion-critica\/#the-dom\">DOM<\/a> como antes, pero tambi\u00e9n debe monitorear el campo para los cambios, por lo que <strong>setFormValue() <\/strong>se puede ejecutar:<\/p>\n<pre><code class=\"language-js\">  connectedCallback() {\n\n    const shadow = this.attachShadow({ mode: 'closed' });\n\n    shadow.innerHTML = `\n      &lt;style&gt;input { width: 4em; }&lt;\/style&gt;\n      &lt;input type=\"number\" placeholder=\"age\" min=\"18\" max=\"120\" \/&gt;`;\n\n    \/\/ monitor input values\n    shadow.querySelector('input').addEventListener('input', e =&gt; {\n      this.setValue(e.target.value);\n    });\n\n  }\n<\/code><\/pre>\n<p>Ahora puedes crear un formulario HTML utilizando este componente web que act\u00faa de forma similar a otros campos de formulario:<\/p>\n<pre><code class=\"language-html\">&lt;form id=\"myform\"&gt;\n\n  &lt;input type=\"text\" name=\"your-name\" placeholder=\"name\" \/&gt;\n\n  &lt;input-age name=\"your-age\"&gt;&lt;\/input-age&gt;\n\n  &lt;button&gt;submit&lt;\/button&gt;\n\n&lt;\/form&gt;\n<\/code><\/pre>\n<p>Funciona, pero hay que reconocer que es un poco enrevesado.<\/p>\n<p>Compru\u00e9balo en la <a href=\"https:\/\/codepen.io\/craigbuckler\/pen\/JjWmxwo\">demostraci\u00f3n de CodePen<\/a><\/p>\n<p>Para m\u00e1s informaci\u00f3n, consulta <a href=\"https:\/\/web.dev\/more-capable-form-controls\/\">este art\u00edculo sobre controles de formulario m\u00e1s completos<\/a>.<\/p>\n\n<h2>Resumen<\/h2>\n<p>Los Componentes Web han luchado para ganar acuerdo y adopci\u00f3n en un momento en que los frameworks de JavaScript han crecido en estatura y capacidad. Si vienes de React, <a href=\"https:\/\/kinsta.com\/es\/blog\/bibliotecas-javascript\/#vuejs\">Vue.js<\/a> o <a href=\"https:\/\/kinsta.com\/es\/blog\/php-vs-angular\/#what-is-angular\">Angular<\/a>, los Components Web pueden parecer complejos y torpes, especialmente cuando faltan caracter\u00edsticas como la vinculaci\u00f3n de datos y la gesti\u00f3n de estados.<\/p>\n<p>Hay que limar asperezas, pero el futuro de los Componentes Web es brillante. Son independientes del marco de trabajo, ligeros, r\u00e1pidos y pueden implementar funcionalidades que ser\u00edan imposibles de realizar solo con JavaScript.<\/p>\n<p>Hace una d\u00e9cada, pocos habr\u00edan abordado un sitio sin jQuery, pero los proveedores de navegadores tomaron las partes excelentes y a\u00f1adieron alternativas nativas (como querySelector). Lo mismo ocurrir\u00e1 con los frameworks de JavaScript, y Componentes Web es ese primer paso tentativo.<\/p>\n<p><em>\u00bfTienes alguna duda sobre c\u00f3mo utilizar los Componentes Web? Hablemos de ello en la secci\u00f3n de comentarios.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Todos tenemos proyectos en los que preferir\u00edamos no trabajar. El c\u00f3digo se ha vuelto inmanejable, el alcance del proyecto ha evolucionado, se han aplicado correcciones r\u00e1pidas &#8230;<\/p>\n","protected":false},"author":188,"featured_media":43490,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kinsta_gated_content":false,"_kinsta_gated_content_redirect":"","footnotes":""},"tags":[105,867],"topic":[1337],"class_list":["post-43413","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-html","tag-javascript","topic-herramientas-de-desarrollo-web"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v24.6 (Yoast SEO v24.6) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Una Introducci\u00f3n Completa a los Componentes Web en 2026<\/title>\n<meta name=\"description\" content=\"Los Componentes son una forma est\u00e1ndar de crear elementos HTML reutilizables y modulares sin necesidad de utilizar un framework de JavaScript.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Una Introducci\u00f3n Completa a los Componentes Web en 2026\" \/>\n<meta property=\"og:description\" content=\"Los Componentes son una forma est\u00e1ndar de crear elementos HTML reutilizables y modulares sin necesidad de utilizar un framework de JavaScript.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/\" \/>\n<meta property=\"og:site_name\" content=\"Kinsta\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/kinsta.es\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-09-09T07:34:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-07T14:15:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1460\" \/>\n\t<meta property=\"og:image:height\" content=\"730\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Craig Buckler\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:description\" content=\"Los Componentes son una forma est\u00e1ndar de crear elementos HTML reutilizables y modulares sin necesidad de utilizar un framework de JavaScript.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png\" \/>\n<meta name=\"twitter:creator\" content=\"@craigbuckler\" \/>\n<meta name=\"twitter:site\" content=\"@Kinsta_ES\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Craig Buckler\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/\"},\"author\":{\"name\":\"Craig Buckler\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/715d986404b06691ab3014e06596908e\"},\"headline\":\"Una Introducci\u00f3n Completa a los Componentes Web en 2026\",\"datePublished\":\"2021-09-09T07:34:27+00:00\",\"dateModified\":\"2025-02-07T14:15:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/\"},\"wordCount\":3111,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/es\/#organization\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png\",\"keywords\":[\"html\",\"JavaScript\"],\"articleSection\":[\"Sin Categor\u00eda\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/\",\"url\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/\",\"name\":\"Una Introducci\u00f3n Completa a los Componentes Web en 2026\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/es\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png\",\"datePublished\":\"2021-09-09T07:34:27+00:00\",\"dateModified\":\"2025-02-07T14:15:10+00:00\",\"description\":\"Los Componentes son una forma est\u00e1ndar de crear elementos HTML reutilizables y modulares sin necesidad de utilizar un framework de JavaScript.\",\"breadcrumb\":{\"@id\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#primaryimage\",\"url\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png\",\"contentUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png\",\"width\":1460,\"height\":730,\"caption\":\"Una completa introducci\u00f3n a los componentes web en 2021\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/kinsta.com\/es\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Herramientas de Desarrollo Web\",\"item\":\"https:\/\/kinsta.com\/es\/secciones\/herramientas-de-desarrollo-web\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Una Introducci\u00f3n Completa a los Componentes Web en 2025\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kinsta.com\/es\/#website\",\"url\":\"https:\/\/kinsta.com\/es\/\",\"name\":\"Kinsta\u00ae\",\"description\":\"Soluciones de alojamiento premium, r\u00e1pidas y seguras\",\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/es\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kinsta.com\/es\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kinsta.com\/es\/#organization\",\"name\":\"Kinsta\",\"url\":\"https:\/\/kinsta.com\/es\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg\",\"contentUrl\":\"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg\",\"width\":500,\"height\":500,\"caption\":\"Kinsta\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/kinsta.es\/\",\"https:\/\/x.com\/Kinsta_ES\",\"https:\/\/www.instagram.com\/kinstahosting\/\",\"https:\/\/www.linkedin.com\/company\/kinsta\/\",\"https:\/\/www.pinterest.com\/kinstahosting\/\",\"https:\/\/www.youtube.com\/c\/Kinsta\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/715d986404b06691ab3014e06596908e\",\"name\":\"Craig Buckler\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/kinsta.com\/es\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8e76011e66720bd2e3e24e164aa6f0b2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8e76011e66720bd2e3e24e164aa6f0b2?s=96&d=mm&r=g\",\"caption\":\"Craig Buckler\"},\"description\":\"Freelance UK web developer, writer, and speaker. Has been around a long time and rants about standards and performance.\",\"sameAs\":[\"https:\/\/craigbuckler.com\/\",\"https:\/\/www.linkedin.com\/in\/craigbuckler\",\"https:\/\/x.com\/craigbuckler\",\"https:\/\/www.youtube.com\/channel\/UCQwdl5oBTWGhifS6bRGADMQ\"],\"url\":\"https:\/\/kinsta.com\/es\/blog\/author\/craigbuckler\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Una Introducci\u00f3n Completa a los Componentes Web en 2026","description":"Los Componentes son una forma est\u00e1ndar de crear elementos HTML reutilizables y modulares sin necesidad de utilizar un framework de JavaScript.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/","og_locale":"es_ES","og_type":"article","og_title":"Una Introducci\u00f3n Completa a los Componentes Web en 2026","og_description":"Los Componentes son una forma est\u00e1ndar de crear elementos HTML reutilizables y modulares sin necesidad de utilizar un framework de JavaScript.","og_url":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/","og_site_name":"Kinsta\u00ae","article_publisher":"https:\/\/www.facebook.com\/kinsta.es\/","article_published_time":"2021-09-09T07:34:27+00:00","article_modified_time":"2025-02-07T14:15:10+00:00","og_image":[{"width":1460,"height":730,"url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png","type":"image\/png"}],"author":"Craig Buckler","twitter_card":"summary_large_image","twitter_description":"Los Componentes son una forma est\u00e1ndar de crear elementos HTML reutilizables y modulares sin necesidad de utilizar un framework de JavaScript.","twitter_image":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png","twitter_creator":"@craigbuckler","twitter_site":"@Kinsta_ES","twitter_misc":{"Escrito por":"Craig Buckler","Tiempo de lectura":"15 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#article","isPartOf":{"@id":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/"},"author":{"name":"Craig Buckler","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/715d986404b06691ab3014e06596908e"},"headline":"Una Introducci\u00f3n Completa a los Componentes Web en 2026","datePublished":"2021-09-09T07:34:27+00:00","dateModified":"2025-02-07T14:15:10+00:00","mainEntityOfPage":{"@id":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/"},"wordCount":3111,"commentCount":0,"publisher":{"@id":"https:\/\/kinsta.com\/es\/#organization"},"image":{"@id":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png","keywords":["html","JavaScript"],"articleSection":["Sin Categor\u00eda"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/kinsta.com\/es\/blog\/componentes-web\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/","url":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/","name":"Una Introducci\u00f3n Completa a los Componentes Web en 2026","isPartOf":{"@id":"https:\/\/kinsta.com\/es\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#primaryimage"},"image":{"@id":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png","datePublished":"2021-09-09T07:34:27+00:00","dateModified":"2025-02-07T14:15:10+00:00","description":"Los Componentes son una forma est\u00e1ndar de crear elementos HTML reutilizables y modulares sin necesidad de utilizar un framework de JavaScript.","breadcrumb":{"@id":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kinsta.com\/es\/blog\/componentes-web\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#primaryimage","url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png","contentUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2021\/08\/web-components.png","width":1460,"height":730,"caption":"Una completa introducci\u00f3n a los componentes web en 2021"},{"@type":"BreadcrumbList","@id":"https:\/\/kinsta.com\/es\/blog\/componentes-web\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kinsta.com\/es\/"},{"@type":"ListItem","position":2,"name":"Herramientas de Desarrollo Web","item":"https:\/\/kinsta.com\/es\/secciones\/herramientas-de-desarrollo-web\/"},{"@type":"ListItem","position":3,"name":"Una Introducci\u00f3n Completa a los Componentes Web en 2025"}]},{"@type":"WebSite","@id":"https:\/\/kinsta.com\/es\/#website","url":"https:\/\/kinsta.com\/es\/","name":"Kinsta\u00ae","description":"Soluciones de alojamiento premium, r\u00e1pidas y seguras","publisher":{"@id":"https:\/\/kinsta.com\/es\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kinsta.com\/es\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/kinsta.com\/es\/#organization","name":"Kinsta","url":"https:\/\/kinsta.com\/es\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/","url":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg","contentUrl":"https:\/\/kinsta.com\/es\/wp-content\/uploads\/sites\/8\/2023\/12\/kinsta-logo.jpeg","width":500,"height":500,"caption":"Kinsta"},"image":{"@id":"https:\/\/kinsta.com\/es\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/kinsta.es\/","https:\/\/x.com\/Kinsta_ES","https:\/\/www.instagram.com\/kinstahosting\/","https:\/\/www.linkedin.com\/company\/kinsta\/","https:\/\/www.pinterest.com\/kinstahosting\/","https:\/\/www.youtube.com\/c\/Kinsta"]},{"@type":"Person","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/715d986404b06691ab3014e06596908e","name":"Craig Buckler","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/kinsta.com\/es\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8e76011e66720bd2e3e24e164aa6f0b2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8e76011e66720bd2e3e24e164aa6f0b2?s=96&d=mm&r=g","caption":"Craig Buckler"},"description":"Freelance UK web developer, writer, and speaker. Has been around a long time and rants about standards and performance.","sameAs":["https:\/\/craigbuckler.com\/","https:\/\/www.linkedin.com\/in\/craigbuckler","https:\/\/x.com\/craigbuckler","https:\/\/www.youtube.com\/channel\/UCQwdl5oBTWGhifS6bRGADMQ"],"url":"https:\/\/kinsta.com\/es\/blog\/author\/craigbuckler\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/43413","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/users\/188"}],"replies":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/comments?post=43413"}],"version-history":[{"count":16,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/43413\/revisions"}],"predecessor-version":[{"id":67779,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/posts\/43413\/revisions\/67779"}],"alternate":[{"embeddable":true,"hreflang":"en","title":"English","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43413\/translations\/en"},{"embeddable":true,"hreflang":"fr","title":"French","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43413\/translations\/fr"},{"embeddable":true,"hreflang":"de","title":"German","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43413\/translations\/de"},{"embeddable":true,"hreflang":"es","title":"Spanish","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43413\/translations\/es"},{"embeddable":true,"hreflang":"it","title":"Italian","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43413\/translations\/it"},{"embeddable":true,"hreflang":"pt","title":"Portuguese","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43413\/translations\/pt"},{"embeddable":true,"hreflang":"nl","title":"Dutch","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43413\/translations\/nl"},{"embeddable":true,"hreflang":"sv","title":"Swedish","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43413\/translations\/se"},{"embeddable":true,"hreflang":"ja","title":"Japanese","href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43413\/translations\/jp"},{"href":"https:\/\/kinsta.com\/es\/wp-json\/kinsta\/v1\/posts\/43413\/tree"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/media\/43490"}],"wp:attachment":[{"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/media?parent=43413"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/tags?post=43413"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/kinsta.com\/es\/wp-json\/wp\/v2\/topic?post=43413"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}