{"id":48058,"date":"2021-08-26T11:44:25","date_gmt":"2021-08-26T09:44:25","guid":{"rendered":"https:\/\/kinsta.com\/?p=98073"},"modified":"2023-11-10T12:46:09","modified_gmt":"2023-11-10T11:46:09","slug":"composants-web","status":"publish","type":"post","link":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/","title":{"rendered":"Une introduction compl\u00e8te aux composants web en 2026"},"content":{"rendered":"<p>Nous avons tous des projets sur lesquels nous pr\u00e9f\u00e9rerions ne pas travailler. Le code est devenu ing\u00e9rable, la port\u00e9e a \u00e9volu\u00e9, des corrections rapides ont \u00e9t\u00e9 appliqu\u00e9es par-dessus d&rsquo;autres corrections et la structure s&rsquo;est effondr\u00e9e sous son poids de code spaghetti. Le codage peut \u00eatre une activit\u00e9 d\u00e9sordonn\u00e9e.<\/p>\n<p>Les projets gagnent \u00e0 utiliser des modules simples et ind\u00e9pendants qui ont une seule responsabilit\u00e9. Le code modulaire est encapsul\u00e9, il y a donc moins besoin de se soucier de la mise en \u0153uvre. Tant que vous savez ce qu&rsquo;un module va produire lorsqu&rsquo;il re\u00e7oit un ensemble d&rsquo;entr\u00e9es, vous n&rsquo;avez pas n\u00e9cessairement besoin de comprendre <i>comment<\/i> il a atteint cet objectif.<\/p>\n<p>Appliquer les concepts modulaires \u00e0 un seul <a href=\"https:\/\/kinsta.com\/fr\/blog\/meilleur-langage-programmation-apprendre\/\">langage de programmation<\/a> est simple, mais le d\u00e9veloppement web n\u00e9cessite un m\u00e9lange vari\u00e9 de technologies. Les <a href=\"https:\/\/kinsta.com\/fr\/parts-de-marche-des-navigateurs\/\">navigateurs<\/a> analysent le <a href=\"https:\/\/kinsta.com\/fr\/blog\/html-vs-html5\/\">HTML<\/a>, le CSS et le JavaScript pour rendre le contenu, les styles et les fonctionnalit\u00e9s de la page.<\/p>\n<p>Ils ne se m\u00e9langent pas toujours facilement car :<\/p>\n<ul>\n<li>Le code connexe peut \u00eatre r\u00e9parti entre trois fichiers ou plus<\/li>\n<li>Les styles globaux et les objets JavaScript peuvent interf\u00e9rer les uns avec les autres de mani\u00e8re inattendue.<\/li>\n<\/ul>\n<p>Ces probl\u00e8mes s&rsquo;ajoutent \u00e0 ceux rencontr\u00e9s par les moteurs d&rsquo;ex\u00e9cution des langages, les <a href=\"https:\/\/kinsta.com\/fr\/blog\/bibliotheques-javascript\/\">frameworks<\/a>, les bases de donn\u00e9es et les autres d\u00e9pendances utilis\u00e9es sur le serveur.<\/p>\n<h3>Consultez notre <a href=\"https:\/\/www.youtube.com\/watch?v=hVxZ-te0kio\">guide vid\u00e9o<\/a> sur les composants 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>Que sont les composants web ?<\/h2>\n<p>Un composant web est un moyen de cr\u00e9er un bloc de code encapsul\u00e9, \u00e0 responsabilit\u00e9 unique, qui peut \u00eatre r\u00e9utilis\u00e9 sur n&rsquo;importe quelle page.<\/p>\n<p>Consid\u00e9rez la balise HTML <code><strong>&lt;video&gt;<\/strong><\/code> . Avec une <a href=\"https:\/\/kinsta.com\/fr\/blog\/description-url\/\">URL<\/a>, un spectateur peut utiliser des contr\u00f4les comme la lecture, la pause, le retour en arri\u00e8re, l&rsquo;avance et le r\u00e9glage du volume.<\/p>\n<p>Le style et les fonctionnalit\u00e9s sont fournis, mais vous peux apporter des modifications en utilisant divers attributs et appels API JavaScript. Un nombre quelconque d&rsquo;\u00e9l\u00e9ments <code><strong>&lt;vid\u00e9o&gt;<\/strong><\/code> peuvent \u00eatre plac\u00e9s \u00e0 l&rsquo;int\u00e9rieur d&rsquo;autres balises, et ils n&rsquo;entreront pas en conflit.<\/p>\n<p>Et si vous avez besoin de votre propre fonctionnalit\u00e9 personnalis\u00e9e ? Par exemple, un \u00e9l\u00e9ment indiquant le nombre de mots sur la page ? Il n&rsquo;y a pas (encore) de balise HTML <code><strong>&lt;wordcount&gt;<\/strong><\/code>.<\/p>\n<p>Les frameworks tels que <a href=\"https:\/\/kinsta.com\/fr\/blog\/bibliotheques-javascript\/#reactjs\">React<\/a> et <a href=\"https:\/\/kinsta.com\/fr\/blog\/vue-js\/\">Vue.js<\/a> permettent aux d\u00e9veloppeurs de cr\u00e9er des composants web dont le contenu, le style et la fonctionnalit\u00e9 peuvent \u00eatre d\u00e9finis dans un seul fichier JavaScript. Ils permettent de r\u00e9soudre de nombreux probl\u00e8mes de programmation complexes mais n&rsquo;oubliez pas que :<\/p>\n<ul>\n<li>Vous devez apprendre \u00e0 utiliser ce framework et mettre \u00e0 jour votre code \u00e0 mesure qu&rsquo;il \u00e9volue.<\/li>\n<li>Un composant \u00e9crit pour un framework est rarement compatible avec un autre.<\/li>\n<li>Les frameworks gagnent et perdent en popularit\u00e9. Vous deviendrez d\u00e9pendant des caprices et des priorit\u00e9s de l&rsquo;\u00e9quipe de d\u00e9veloppement et des utilisateurs.<\/li>\n<li>Les composants web standard peuvent ajouter des fonctionnalit\u00e9s au navigateur, ce qui est difficile \u00e0 r\u00e9aliser en JavaScript seul (comme le Shadow DOM).<\/li>\n<\/ul>\n<p>Heureusement, les concepts populaires introduits dans les biblioth\u00e8ques et les frameworks font g\u00e9n\u00e9ralement leur chemin dans les normes web. Cela a pris du temps, mais les composants web sont arriv\u00e9s.<\/p>\n\n<h2>Une br\u00e8ve histoire des composants web<\/h2>\n<p>Apr\u00e8s de nombreux faux d\u00e9parts sp\u00e9cifiques aux fournisseurs, le concept de composants web standard a \u00e9t\u00e9 pr\u00e9sent\u00e9 pour la premi\u00e8re fois par <a href=\"https:\/\/fronteers.nl\/congres\/2011\/sessions\/web-components-and-model-driven-views-alex-russell\">Alex Russell lors de la conf\u00e9rence Fronteers en 2011<\/a>. La <a href=\"https:\/\/github.com\/Polymer\/polymer\">biblioth\u00e8que Polymer<\/a> de Google (un polyfill bas\u00e9 sur les propositions actuelles) est arriv\u00e9e deux ans plus tard, mais les premi\u00e8res impl\u00e9mentations ne sont apparues dans Chrome et Safari qu&rsquo;en 2016.<\/p>\n<p>Les fournisseurs de navigateurs ont mis du temps \u00e0 n\u00e9gocier les d\u00e9tails, mais les composants web ont \u00e9t\u00e9 ajout\u00e9s \u00e0 Firefox en 2018 et \u00e0 Edge en 2020 (lorsque Microsoft a adopt\u00e9 le moteur Chromium).<\/p>\n<p>Il est compr\u00e9hensible que peu de d\u00e9veloppeurs aient voulu ou pu adopter les composants web, mais nous avons finalement atteint un bon niveau de prise en charge des navigateurs avec des API stables. Tout n&rsquo;est pas parfait, mais ils constituent une alternative de plus en plus viable aux composants bas\u00e9s sur des frameworks.<\/p>\n<p>M\u00eame si vous n&rsquo;\u00eates pas encore pr\u00eat \u00e0 abandonner votre pr\u00e9f\u00e9r\u00e9, les composants web sont compatibles avec <i>tous les<\/i> frameworks et les API seront prises en charge pendant des ann\u00e9es.<\/p>\n<p>Des d\u00e9p\u00f4tes de composants web pr\u00e9-construits sont disponibles pour que tout le monde puisse y jeter un \u0153il :<\/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;mais \u00e9crire votre propre code est plus amusant !<\/p>\n<p>Ce tutoriel fournit une introduction compl\u00e8te aux composants web \u00e9crits sans framework JavaScript. Vous apprendrez ce qu&rsquo;ils sont et comment les adapter \u00e0 vos projets web. Vous aurez besoin de quelques connaissances en <a href=\"https:\/\/kinsta.com\/fr\/blog\/html-vs-html5\/\">HTML5<\/a>, CSS et JavaScript.<\/p>\n<h2>Commencer \u00e0 utiliser les composants web<\/h2>\n<p>Les composants web sont des \u00e9l\u00e9ments HTML personnalis\u00e9s tels que <code><strong>&lt;hello-world&gt;&lt;\/hello-world&gt;<\/strong><\/code>. Le nom doit contenir un tiret pour ne jamais entrer en conflit avec des \u00e9l\u00e9ments officiellement pris en charge dans la sp\u00e9cification HTML.<\/p>\n<p>Vous devez d\u00e9finir une classe ES2015 pour contr\u00f4ler l&rsquo;\u00e9l\u00e9ment. Elle peut porter n&rsquo;importe quel nom, mais HelloWorld est une pratique courante. Elle doit \u00e9tendre l&rsquo;<a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/HTMLElement\">interface HTMLElement<\/a>, qui repr\u00e9sente les propri\u00e9t\u00e9s et m\u00e9thodes par d\u00e9faut de chaque \u00e9l\u00e9ment HTML.<\/p>\n<p><strong>Note :<\/strong> <a href=\"https:\/\/kinsta.com\/fr\/blog\/navigateur-le-plus-sur\/#3-firefox\">Firefox<\/a> permet d&rsquo;\u00e9tendre des \u00e9l\u00e9ments HTML sp\u00e9cifiques tels que HTMLParagraphElement, HTMLImageElement ou HTMLButtonElement. Ceci n&rsquo;est pas pris en charge par les autres navigateurs et ne te permet pas de cr\u00e9er un Shadow DOM.<\/p>\n<p>Pour faire quoi que ce soit d&rsquo;utile, la classe n\u00e9cessite une m\u00e9thode nomm\u00e9e <strong>connectedCallback()<\/strong> qui est invoqu\u00e9e lorsque l&rsquo;\u00e9l\u00e9ment est ajout\u00e9 \u00e0 un document :<\/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>Dans cet exemple, le texte de l&rsquo;\u00e9l\u00e9ment est d\u00e9fini comme \u00ab Hello World \u00bb<\/p>\n<p>La classe doit \u00eatre enregistr\u00e9e aupr\u00e8s du <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/CustomElementRegistry\">CustomElementRegistry<\/a> pour la d\u00e9finir comme gestionnaire d&rsquo;un \u00e9l\u00e9ment sp\u00e9cifique :<\/p>\n<pre><code class=\"language-html\">customElements.define( 'hello-world', HelloWorld ) ;\n<\/code><\/pre>\n<p>Le navigateur associe maintenant l&rsquo;\u00e9l\u00e9ment <code><strong>&lt;hello-world&gt;<\/strong><\/code> \u00e0 votre classe <strong>HelloWorld<\/strong> lorsque votre JavaScript est charg\u00e9 (par ex <code><strong>&lt;script type=\"module\" src=\".\/helloworld.js\"&gt;&lt;\/script&gt;<\/strong><\/code>).<\/p>\n<p>Vous avez maintenant un \u00e9l\u00e9ment personnalis\u00e9 !<\/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=wO2OBQxnzO\" data-secret=\"wO2OBQxnzO\" scrolling=\"no\" frameborder=\"0\" height=\"300\"><\/iframe><\/p>\n<p><a href=\"https:\/\/codepen.io\/craigbuckler\/pen\/WNpaxPN\">D\u00e9monstration CodePen<\/a><\/p>\n<p>Ce composant peut \u00eatre styl\u00e9 en CSS comme n&rsquo;importe quel autre \u00e9l\u00e9ment :<\/p>\n<pre><code class=\"language-css\">hello-world {\n  font-weight: bold;\n  coulor: red;\n}\n<\/code><\/pre>\n<h3>Ajout d&rsquo;attributs<\/h3>\n<p>Ce composant n&rsquo;est pas utile puisque le m\u00eame texte est \u00e9dit\u00e9 quoi qu&rsquo;il arrive. Comme tout autre \u00e9l\u00e9ment, nous pouvons ajouter des attributs HTML :<\/p>\n<pre><code class=\"language-html\">&lt;hello-world name=\"Craig\"&gt;&lt;\/hello-world&gt;\n<\/code><\/pre>\n<p>On pourrait ainsi remplacer le texte pour que \u00ab Hello Craig ! \u00bb s&rsquo;affiche. Pour y parvenir, vous pouvez ajouter une fonction <strong>constructor()<\/strong> \u00e0 la classe <strong>HelloWorld<\/strong>, qui est ex\u00e9cut\u00e9e lorsque chaque objet est cr\u00e9\u00e9. Elle doit :<\/p>\n<ol>\n<li>Appeller la m\u00e9thode <strong>super()<\/strong> pour initialiser le HTMLElement parent, et<\/li>\n<li>Effectuer d&rsquo;autres initialisations. Dans ce cas, nous d\u00e9finirons une propri\u00e9t\u00e9 <strong>name<\/strong> qui sera d\u00e9finie par d\u00e9faut sur \u00ab World \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...<\/code><\/pre>\n<p>Votre composant ne se soucie que de l&rsquo;attribut <strong>name<\/strong>. Une propri\u00e9t\u00e9 statique <strong>observedAttributes()<\/strong> doit renvoyer un tableau de propri\u00e9t\u00e9s \u00e0 observer :<\/p>\n<pre><code class=\"language-js\">\/\/ components attributes\nstatic get observedAttributes() {\n  return ['name'] ;\n}\n<\/code><\/pre>\n<p>Une m\u00e9thode <strong>attributeChangedCallback()<\/strong> est appel\u00e9e lorsqu&rsquo;un attribut est d\u00e9fini dans le HTML ou modifi\u00e9 \u00e0 l&rsquo;aide de JavaScript. On lui passe le nom de la propri\u00e9t\u00e9, l&rsquo;ancienne valeur et la nouvelle valeur :<\/p>\n<pre><code class=\"language-js\">\/\/ attribut change\nattributeChangedCallback(property, oldValue, newValue) {\n\n  if (oldValue === newValue) return ;\n  this[ property ] = newValue ;\n\n}\n<\/code><\/pre>\n<p>Dans cet exemple, seule la propri\u00e9t\u00e9 <strong>name<\/strong> sera mise \u00e0 jour, mais vous pourrez ajouter des propri\u00e9t\u00e9s suppl\u00e9mentaires si n\u00e9cessaire.<\/p>\n<p>Enfin, vous devez modifier le message dans la m\u00e9thode <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\">D\u00e9monstration CodePen<\/a><\/p>\n<h3>M\u00e9thodes du cycle de vie<\/h3>\n<p>Le navigateur appelle automatiquement six m\u00e9thodes tout au long du cycle de vie de l&rsquo;\u00e9tat du composant web. La liste compl\u00e8te est fournie ici, bien que vous ayez d\u00e9j\u00e0 vu les quatre premi\u00e8res dans les exemples ci-dessus :<\/p>\n<h4>constructor()<\/h4>\n<p>Il est appel\u00e9 lorsque le composant est initialis\u00e9 pour la premi\u00e8re fois. Il doit appeler <strong>super()<\/strong> et peut d\u00e9finir tous les param\u00e8tres par d\u00e9faut ou effectuer d&rsquo;autres processus de pr\u00e9-rendu.<\/p>\n<h4>static observedAttributes()<\/h4>\n<p>Renvoie un tableau d&rsquo;attributs que le navigateur observera.<\/p>\n<h4>attributeChangedCallback(propertyName,<strong> oldValue, newValue)<\/strong><\/h4>\n<p>Appel\u00e9 chaque fois qu&rsquo;un attribut observ\u00e9 est modifi\u00e9. Ceux d\u00e9finis en HTML sont transmis imm\u00e9diatement, mais JavaScript peut les modifier :<\/p>\n<pre><code class=\"language-js\">document.querySelector('hello-world').setAttribute('name', 'Everyone') ;\n<\/code><\/pre>\n<p>La m\u00e9thode peut avoir besoin de d\u00e9clencher un nouveau rendu lorsque cela se produit.<\/p>\n<h4>connectedCallback()<\/h4>\n<p>Cette fonction est appel\u00e9e lorsque le composant web est ajout\u00e9 \u00e0 un DOM (Document Object Model). Elle doit ex\u00e9cuter tout rendu n\u00e9cessaire.<\/p>\n<h4>disconnectedCallback()<\/h4>\n<p>Cette fonction est appel\u00e9e lorsque le composant web est retir\u00e9 d&rsquo;un DOM. Cela peut \u00eatre utile si vous devez faire le m\u00e9nage, par exemple en supprimant l&rsquo;\u00e9tat stock\u00e9 ou en abandonnant les <a href=\"https:\/\/kinsta.com\/fr\/blog\/admin-ajax\/\">requ\u00eates Ajax<\/a>.<\/p>\n<h4>adoptedCallback()<\/h4>\n<p>Cette fonction est appel\u00e9e lorsqu&rsquo;un composant web est d\u00e9plac\u00e9 d&rsquo;un document \u00e0 un autre. Vous trouverez peut-\u00eatre une utilit\u00e9 \u00e0 cette fonction, bien que j&rsquo;aie eu du mal \u00e0 penser \u00e0 un quelconque cas !<\/p>\n<h2>Comment les composants web interagissent avec les autres \u00e9l\u00e9ments<\/h2>\n<p>Les composants web offrent certaines fonctionnalit\u00e9s uniques que vous ne trouverez pas dans les frameworks JavaScript.<\/p>\n<h3>Le Shadow DOM<\/h3>\n<p>M\u00eame si le composant web que nous avons construit ci-dessus fonctionne, il n&rsquo;est pas \u00e0 l&rsquo;abri des interf\u00e9rences ext\u00e9rieures, et CSS ou JavaScript pourraient le modifier. De m\u00eame, les styles que vous d\u00e9finissez pour votre composant pourraient fuir et affecter les autres.<\/p>\n<p>Le Shadow DOM r\u00e9sout ce probl\u00e8me d&rsquo;encapsulation en attachant un DOM s\u00e9par\u00e9 au composant web avec :<\/p>\n<pre><code class=\"language-js\">const shadow = this.attachShadow({ mode : 'closed' }) ;\n<\/code><\/pre>\n<p>Le mode peut \u00eatre soit :<\/p>\n<ol>\n<li><strong>\u00ab open \u00bb<\/strong> &#8211; Le JavaScript dans la page externe peut acc\u00e9der au Shadow DOM (en utilisant <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/Element\/shadowRoot\">Element.shadowRoot<\/a>), ou<\/li>\n<li><strong>\u00ab closed \u00bb<\/strong> &#8211; le Shadow DOM n&rsquo;est accessible que dans le composant web.<\/li>\n<\/ol>\n<p>Le Shadow DOM peut \u00eatre manipul\u00e9 comme n&rsquo;importe quel autre \u00e9l\u00e9ment 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>Le composant rend maintenant le texte \u00ab Hello \u00bb \u00e0 l&rsquo;int\u00e9rieur d&rsquo;un \u00e9l\u00e9ment <code><strong>&lt;p&gt;<\/strong><\/code> et lui donne un style. Il ne peut pas \u00eatre modifi\u00e9 par JavaScript ou CSS en dehors du composant, bien que certains styles tels que la <a href=\"https:\/\/kinsta.com\/fr\/blog\/polices-html\/\">police<\/a> et la couleur soient h\u00e9rit\u00e9s de la page car ils n&rsquo;ont pas \u00e9t\u00e9 d\u00e9finis explicitement.<\/p>\n<p><a href=\"https:\/\/codepen.io\/craigbuckler\/pen\/rNyqyJJ\">D\u00e9monstration CodePen<\/a><\/p>\n<p>Les styles attribu\u00e9s \u00e0 ce composant web ne peuvent pas affecter les autres paragraphes de la page ni m\u00eame les autres composants <code><strong>&lt;hello-world&gt;<\/strong><\/code>.<\/p>\n<p>Notez que le s\u00e9lecteur CSS <code>:host<\/code> peut donner un style \u00e0 l&rsquo;\u00e9l\u00e9ment externe <code><strong>&lt;hello-world&gt;<\/strong><\/code> \u00e0 partir du composant web :<\/p>\n<pre><code class=\"language-css\">:host {\n  transform: rotate(180deg);\n}<\/code><\/pre>\n<p>Vous pouvez aussi d\u00e9finir des styles \u00e0 appliquer lorsque l&rsquo;\u00e9l\u00e9ment utilise une classe sp\u00e9cifique, par ex <code><strong>&lt;hello-world class=\"rotate90\"&gt;<\/strong><\/code>:<\/p>\n<pre><code class=\"language-css\">:host(.rotate90) {\n  transform: rotate(90deg);\n}\n<\/code><\/pre>\n<h3>Mod\u00e8les HTML<\/h3>\n<p>D\u00e9finir du HTML \u00e0 l&rsquo;int\u00e9rieur d&rsquo;un script peut devenir peu pratique pour les composants web plus complexes. Un mod\u00e8le vous permet de d\u00e9finir un morceau de HTML dans votre page que votre composant web peut utiliser. Cela pr\u00e9sente plusieurs avantages :<\/p>\n<ol>\n<li>Vous pouvez modifier le code HTML sans avoir \u00e0 r\u00e9\u00e9crire les cha\u00eenes de caract\u00e8res dans votre JavaScript.<\/li>\n<li>Les composants peuvent \u00eatre personnalis\u00e9s sans avoir \u00e0 cr\u00e9er des classes JavaScript distinctes pour chaque type.<\/li>\n<li>Il est plus facile de d\u00e9finir le HTML dans le HTML &#8211; et il peut \u00eatre modifi\u00e9 sur le serveur ou le client avant le rendu du composant.<\/li>\n<\/ol>\n<p>Les mod\u00e8les sont d\u00e9finis dans une balise <code><strong>&lt;Template&gt;<\/strong><\/code> et il est pratique d&rsquo;attribuer un ID pour pouvoir le r\u00e9f\u00e9rencer dans la classe du composant. Dans cet exemple, trois paragraphes pour afficher le message \u00ab Hello \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; &lt;p class=\"hw-text\"&gt;.\n\n&lt;\/template&gt;\n<\/code><\/pre>\n<p>La classe de composant web peut acc\u00e9der \u00e0 ce mod\u00e8le, obtenir son contenu et <a href=\"https:\/\/kinsta.com\/fr\/blog\/cloner-votre-site-wordpress\/\">cloner<\/a> les \u00e9l\u00e9ments pour s&rsquo;assurer que vous cr\u00e9ez un fragment DOM unique partout o\u00f9 il est utilis\u00e9 :<\/p>\n<pre><code class=\"language-js\">const template = document.getElementById('hello-world').content.cloneNode(true) ;<\/code><\/pre>\n<p>Le DOM peut \u00eatre modifi\u00e9 et ajout\u00e9 directement au 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\">D\u00e9monstration CodePen<\/a><\/p>\n<h3>Slots de mod\u00e8le<\/h3>\n<p>Les slots vous permettent de personnaliser un mod\u00e8le. Supposons que vous voulez utiliser votre composant web <code><strong>&lt;hello-world&gt;<\/strong><\/code> mais placer le message dans un titre <strong>&lt;h1&gt;<\/strong> dans le Shadow DOM. Vous pourrez \u00e9crire ce code :<\/p>\n<pre><code class=\"language-html\">&lt;hello-world name=\"Craig\"&gt;\n\n  &lt;h1 slot=\"msgtext\"&gt;Hello D\u00e9faut!&lt;\/h1&gt;\n\n&lt;\/hello-world&gt;\n<\/code><\/pre>\n<p>(Note l&rsquo;attribut <strong>slot <\/strong>.)<\/p>\n<p>Vous pourrez \u00e9ventuellement vouloir ajouter d&rsquo;autres \u00e9l\u00e9ments, comme un autre paragraphe :<\/p>\n<pre><code class=\"language-html\">&lt;hello-world name=\"Craig\"&gt;\n\n  &lt;h1 slot=\"msgtext\"&gt;Hello D\u00e9faut!&lt;\/h1&gt;\n  &lt;p&gt;This text will become part of the document.&lt;\/p&gt;\n\n&lt;\/hello-world&gt;<\/code><\/pre>\n<p>Les slots peuvent maintenant \u00eatre mis en \u0153uvre dans votre mod\u00e8le :<\/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 attribut de slot d&rsquo;\u00e9l\u00e9ment d\u00e9fini sur \u00ab msgtext \u00bb (l&rsquo;\u00e9l\u00e9ment <code><strong>&lt;h1&gt;<\/strong><\/code>) est ins\u00e9r\u00e9 \u00e0 l&rsquo;endroit o\u00f9 il y a un \u00e9l\u00e9ment <code><strong>&lt;slot&gt;<\/strong><\/code> nomm\u00e9 \u00ab msgtext \u00bb Le <code><strong>&lt;p&gt;<\/strong><\/code> n&rsquo;a pas de nom de slot attribu\u00e9, mais il est utilis\u00e9 dans le prochain \u00e9l\u00e9ment sans nom disponible <code><strong>&lt;slot&gt;<\/strong><\/code>. En effet, le mod\u00e8le devient :<\/p>\n<pre><code class=\"language-html\">&lt;emballage 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 a part of the component.&lt;\/p&gt;\n  &lt;\/slot&gt;\n\n&lt;\/template&gt;\n<\/code><\/pre>\n<p>Ce n&rsquo;est pas aussi simple dans la r\u00e9alit\u00e9. Un <code><strong>&lt;slot&gt;<\/strong><\/code> dans le Shadow DOM <i>pointe<\/i> vers les \u00e9l\u00e9ments ins\u00e9r\u00e9s. Vous ne pouvez y acc\u00e9der qu&rsquo;en localisant un <code><strong>&lt;slot&gt;<\/strong><\/code> puis en utilisant la <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/HTMLSlotElement\/assignedNodes\"> m\u00e9thode .assignedNodes()<\/a> pour renvoyer un tableau enfant interne. La m\u00e9thode <strong>connectedCallback()<\/strong> mise \u00e0 jour :<\/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\">D\u00e9monstration CodePen<\/a><\/p>\n<p>De plus, vous ne pouvez pas donner un style direct aux \u00e9l\u00e9ments ins\u00e9r\u00e9s, bien que vous puissiez cibler des slots sp\u00e9cifiques dans votre composant web :<\/p>\n<pre><code class=\"language-html\">&lt;Template id=\"hello-world\"&gt;\n\n  &lt;style&gt;\n    slot[name=\"msgtext\"] {coulor : 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>Les slots de <a href=\"https:\/\/kinsta.com\/fr\/blog\/hierarchie-des-modeles-wordpress\/\">mod\u00e8le<\/a> sont un peu inhabituels, mais l&rsquo;un des avantages est que votre contenu sera affich\u00e9 si JavaScript ne s&rsquo;ex\u00e9cute pas. Ce code montre un titre et un paragraphe par d\u00e9faut qui ne sont remplac\u00e9s que lorsque la classe du composant web s&rsquo;ex\u00e9cute bien :<\/p>\n<pre><code class=\"language-html\">&lt;hello-world name=\"Craig\"&gt;\n\n  &lt;h1 slot=\"msgtext\"&gt;Hello D\u00e9faut!&lt;\/h1&gt;\n  &lt;p&gt;This text will become a part of the component.&lt;\/p&gt;\n\n&lt;\/hello-world&gt;<\/code><\/pre>\n<p>Vous pourrez donc mettre en place une forme d&rsquo;am\u00e9lioration progressive, m\u00eame si ce n&rsquo;est qu&rsquo;un message \u00ab <i>Vous avez besoin de JavaScript \u00bb <\/i>!<\/p>\n<h3>Le Shadow DOM d\u00e9claratif<\/h3>\n<p>Les exemples ci-dessus construisent un Shadow DOM en utilisant JavaScript. Cela reste la seule option, mais un Shadow DOM d\u00e9claratif exp\u00e9rimental est en cours de d\u00e9veloppement pour <a href=\"https:\/\/kinsta.com\/fr\/blog\/meilleures-extensions-chrome\/\">Chrome<\/a>. Cela permet un rendu c\u00f4t\u00e9 serveur et \u00e9vite tout d\u00e9calage de mise en page ou flash de contenu non stylis\u00e9.<\/p>\n<p>Le code suivant est d\u00e9tect\u00e9 par l&rsquo;analyseur HTML, qui cr\u00e9e un Shadow DOM identique \u00e0 celui que tu as cr\u00e9\u00e9 dans la derni\u00e8re section (tu devras mettre \u00e0 jour le message si n\u00e9cessaire) :<\/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;\n<\/code><\/pre>\n<p>La fonctionnalit\u00e9 n&rsquo;est disponible dans aucun navigateur, et il n&rsquo;y a aucune garantie qu&rsquo;elle atteigne Firefox ou Safari. Vous pouvez en savoir <a href=\"https:\/\/web.dev\/declarative-shadow-dom\/\">plus sur le Shadow DOM d\u00e9claratif<\/a>, et un polyfill est simple, mais sachez que l&rsquo;impl\u00e9mentation pourrait changer.<\/p>\n<h3>\u00c9v\u00e9nements Shadow DOM<\/h3>\n<p>Votre composant web peut attacher des \u00e9v\u00e9nements \u00e0 n&rsquo;importe quel \u00e9l\u00e9ment du Shadow DOM comme vous le feriez dans le DOM de la page, par exemple pour \u00e9couter les \u00e9v\u00e9nements de clic sur tous les enfants internes :<\/p>\n<pre><code class=\"language-js\">shadow.addEventListener('click', e =&gt; {\n\n  \/\/ do something\n\n}) ;\n<\/code><\/pre>\n<p>Si vous utilisez <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/Event\/stopPropagation\">stopPropagation<\/a>, l&rsquo;\u00e9v\u00e9nement remontera dans le DOM de la page, mais il sera recibl\u00e9. Ainsi, il semble provenir de votre \u00e9l\u00e9ment personnalis\u00e9 plut\u00f4t que des \u00e9l\u00e9ments qui le composent.<\/p>\n<h2>Utiliser des composants web dans d&rsquo;autres frameworks<\/h2>\n<p>Tout composant web que vous cr\u00e9ez fonctionnera dans tous les <a href=\"https:\/\/kinsta.com\/fr\/blog\/bibliotheques-javascript\/#the-most-popular-javascript-frameworks\">frameworks JavaScript<\/a>. Aucun d&rsquo;entre eux ne conna\u00eet les \u00e9l\u00e9ments HTML ou ne s&rsquo;en soucie &#8211;votre <code><strong>&lt;hello-world&gt;<\/strong><\/code> sera trait\u00e9 de la m\u00eame fa\u00e7on qu&rsquo;un <code><strong>&lt;div&gt;<\/strong><\/code> et plac\u00e9 dans le DOM o\u00f9 la classe sera activ\u00e9e.<\/p>\n<p><a href=\"https:\/\/custom-elements-everywhere.com\/\">custom-elements-everywhere.com<\/a> fournit une liste de frameworks et de notes sur les composants web. La plupart sont enti\u00e8rement compatibles, bien que React.js pr\u00e9sente quelques difficult\u00e9s. Il est possible d&rsquo;utiliser <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;mais :<\/p>\n<ul>\n<li>React ne peut transmettre que des types de donn\u00e9es primitifs aux attributs HTML (pas les tableaux ou les objets)<\/li>\n<li>React ne peut pas \u00e9couter les \u00e9v\u00e9nements des composants web, vous devez donc joindre manuellement vos propres gestionnaires.<\/li>\n<\/ul>\n<h2>Critiques et probl\u00e8mes li\u00e9s aux composants web<\/h2>\n<p>Les composants web se sont consid\u00e9rablement am\u00e9lior\u00e9s, mais certains aspects peuvent \u00eatre d\u00e9licats \u00e0 g\u00e9rer.<\/p>\n<h3>Difficult\u00e9s de stylisation<\/h3>\n<p>La stylisation des composants web pose quelques difficult\u00e9s, surtout si vous voulez remplacer les styles scop\u00e9s. Il existe de nombreuses solutions :<\/p>\n<ol>\n<li><strong>\u00c9vitez d&rsquo;utiliser le Shadow DOM.<\/strong> Vous pouvez ajouter du contenu directement \u00e0 votre \u00e9l\u00e9ment personnalis\u00e9, mais tout autre JavaScript pourrait le modifier accidentellement ou malicieusement.<\/li>\n<li><strong>Utilisez les classes <code>:host<\/code><\/strong>. Comme nous l&rsquo;avons vu plus haut, le <a href=\"https:\/\/kinsta.com\/fr\/blog\/optimiser-chemin-rendu-critique\/#optimize-css\">scoped CSS<\/a> peut appliquer des styles sp\u00e9cifiques lorsqu&rsquo;une classe est appliqu\u00e9e \u00e0 l&rsquo;\u00e9l\u00e9ment personnalis\u00e9.<\/li>\n<li><strong>V\u00e9rifiez les propri\u00e9t\u00e9s personnalis\u00e9es CSS (variables).<\/strong> Les propri\u00e9t\u00e9s personnalis\u00e9es se retrouvent en cascade dans les composants web, donc, si votre \u00e9l\u00e9ment utilise <code><strong>var(--my-color)<\/strong><\/code> vous pouvez d\u00e9finir <code><strong>--my-color<\/strong><\/code> dans un conteneur externe (comme <code><strong>:root<\/strong><\/code>), et il sera utilis\u00e9.<\/li>\n<li><strong>Profitez des parties d&rsquo;ombre.<\/strong> Le nouveau <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/CSS\/::part\">s\u00e9lecteur ::part()<\/a> peut donner du style \u00e0 un composant int\u00e9rieur qui a un attribut part, c&rsquo;est-\u00e0-dire <code><strong>&lt;h1 part=\"heading\"&gt;<\/strong><\/code> dans un <code><strong>&lt;hello-world&gt;<\/strong><\/code> peut \u00eatre stylis\u00e9 avec le s\u00e9lecteur <code><strong>hello-world::part(heading)<\/strong><\/code>.<\/li>\n<li><strong>Transmettez une cha\u00eene de styles.<\/strong> Vous pouvez les transmettre en tant qu&rsquo;attribut \u00e0 appliquer dans un bloc <code><strong>&lt;style&gt;<\/strong><\/code>.<\/li>\n<\/ol>\n<p>Aucune n&rsquo;est id\u00e9ale, et vous devrez planifier soigneusement la fa\u00e7on dont les autres utilisateurs peuvent personnaliser votre composant web.<\/p>\n<h3>Entr\u00e9es ignor\u00e9es<\/h3>\n<p>Tout <code><strong>&lt;input&gt;<\/strong><\/code>, <code><strong>&lt;textarea&gt;<\/strong><\/code>, ou <code><strong>&lt;selection&gt;<\/strong><\/code> dans votre Shadow DOM n&rsquo;est pas automatiquement associ\u00e9 au formulaire qui le contient. Les premiers adeptes des composants web ajoutaient des champs cach\u00e9s au DOM de la page ou utilisaient l&rsquo;<a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/FormData\">interface FormData<\/a> pour mettre \u00e0 jour les valeurs. Ni l&rsquo;un ni l&rsquo;autre ne sont particuli\u00e8rement pratiques et rompent l&rsquo;encapsulation des composants web.<\/p>\n<p>La nouvelle interface ElementInternals permet \u00e0 un composant web <a href=\"https:\/\/kinsta.com\/fr\/blog\/hooks-wordpress\/\">de se hooker<\/a> aux formulaires afin de pouvoir d\u00e9finir des valeurs personnalis\u00e9es et la validit\u00e9. Elle est impl\u00e9ment\u00e9e dans Chrome, mais un <a href=\"https:\/\/www.npmjs.com\/package\/element-internals-polyfill\">polyfill est disponible<\/a> pour les autres navigateurs.<\/p>\n<p>Pour faire une d\u00e9monstration, vous allez cr\u00e9er un <code><strong>&lt;input-age name=\"your-age\"&gt;&lt;\/input-age&gt;<\/strong><\/code> basique. La classe doit avoir une valeur statique <strong>formAssociated <\/strong>d\u00e9finie sur true et, en option, une m\u00e9thode <strong>formAssociatedCallback()<\/strong> peut \u00eatre appel\u00e9e lorsque le formulaire externe est associ\u00e9 :<\/p>\n<pre><code class=\"language-js\">\/\/ Composant web &lt;input-age&gt\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>Le constructeur doit maintenant ex\u00e9cuter la m\u00e9thode <strong>attachInternals()<\/strong>, qui permet au composant de communiquer avec le formulaire et d&rsquo;autres <a href=\"https:\/\/kinsta.com\/fr\/blog\/qu-est-javascript\/\">codes JavaScript<\/a> qui veulent inspecter la valeur ou la validation :<\/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>La m\u00e9thode <strong>setFormValue()<\/strong> de l&rsquo;ElementInternal d\u00e9finit la valeur de l&rsquo;\u00e9l\u00e9ment pour le formulaire parent initialis\u00e9 avec une cha\u00eene vide ici (on peut aussi lui passer un objet FormData avec plusieurs paires nom\/valeur). Les autres propri\u00e9t\u00e9s et m\u00e9thodes comprennent :<\/p>\n<ul>\n<li><strong>form <\/strong>: le formulaire parent<\/li>\n<li><strong>labels <\/strong>: un tableau d&rsquo;\u00e9l\u00e9ments qui lab\u00e9lisent le composant<\/li>\n<li>Des options de <a href=\"https:\/\/developer.mozilla.org\/docs\/Web\/API\/Constraint_validation\">Constraint Validation API<\/a> telles que willValidate, checkValidity et validationMessage<\/li>\n<\/ul>\n<p>La m\u00e9thode <strong>connectedCallback()<\/strong> cr\u00e9e un <a href=\"https:\/\/kinsta.com\/fr\/blog\/optimiser-chemin-rendu-critique\/#the-dom\">DOM<\/a> Shadow comme pr\u00e9c\u00e9demment, mais doit \u00e9galement surveiller les changements du champ, afin que <strong>setFormValue()<\/strong> puisse \u00eatre ex\u00e9cut\u00e9 :<\/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 { largeur : 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>Vous pouvez maintenant cr\u00e9er un formulaire HTML \u00e0 l&rsquo;aide de ce composant web qui agit de mani\u00e8re similaire aux autres champs de formulaire :<\/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>Cela fonctionne, mais il faut avouer que c&rsquo;est un peu alambiqu\u00e9.<\/p>\n<p>V\u00e9rifiez-le dans la <a href=\"https:\/\/codepen.io\/craigbuckler\/pen\/JjWmxwo\">d\u00e9monstration CodePen<\/a><\/p>\n<p>Pour plus d&rsquo;informations, consultez <a href=\"https:\/\/web.dev\/more-capable-form-controls\/\" target=\"_blank\" rel=\"noopener noreferrer\">cet article sur les contr\u00f4les de formulaire plus performants<\/a>.<\/p>\n\n<h2>R\u00e9sum\u00e9<\/h2>\n<p>Les composants web ont eu du mal \u00e0 faire l&rsquo;unanimit\u00e9 et \u00e0 \u00eatre adopt\u00e9s \u00e0 une \u00e9poque o\u00f9 les frameworks JavaScript ont gagn\u00e9 en stature et en capacit\u00e9s. Si vous venez de React, <a href=\"https:\/\/kinsta.com\/fr\/blog\/bibliotheques-javascript\/#vuejs\">Vue.js<\/a> ou <a href=\"https:\/\/kinsta.com\/fr\/blog\/php-vs-angular\/#what-is-angular\">Angular<\/a>, les composants web peuvent sembler complexes et encombrants, surtout s&rsquo;il manque des fonctionnalit\u00e9s comme la liaison de donn\u00e9es et la gestion d&rsquo;\u00e9tat.<\/p>\n<p>Il y a des probl\u00e8mes \u00e0 r\u00e9gler, mais l&rsquo;avenir des composants web est prometteur. Ils sont ind\u00e9pendants du framework, l\u00e9gers, rapides et peuvent mettre en \u0153uvre des fonctionnalit\u00e9s qui seraient impossibles uniquement en JavaScript.<\/p>\n<p>Il y a dix ans, peu de gens se seraient attaqu\u00e9s \u00e0 un site sans <a href=\"https:\/\/kinsta.com\/fr\/blog\/qu-est-jquery\/\">jQuery<\/a>, mais les fournisseurs de navigateurs ont pris les meilleures parties et ont ajout\u00e9 des alternatives natives (comme querySelector). Il en sera de m\u00eame pour les frameworks JavaScript, et les composants web sont cette premi\u00e8re \u00e9tape provisoire.<\/p>\n<p><em>Vous avez des questions sur la fa\u00e7on d&rsquo;utiliser les composants web ? Parlons-en dans la section des commentaires !<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nous avons tous des projets sur lesquels nous pr\u00e9f\u00e9rerions ne pas travailler. Le code est devenu ing\u00e9rable, la port\u00e9e a \u00e9volu\u00e9, des corrections rapides ont \u00e9t\u00e9 &#8230;<\/p>\n","protected":false},"author":188,"featured_media":48067,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kinsta_gated_content":false,"_kinsta_gated_content_redirect":"","footnotes":""},"tags":[254,535],"topic":[1020],"class_list":["post-48058","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-html","tag-javascript","topic-outils-developpement-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>Une introduction compl\u00e8te aux composants web en 2026<\/title>\n<meta name=\"description\" content=\"Les composants web sont un moyen standard de cr\u00e9er des \u00e9l\u00e9ments HTML r\u00e9utilisables et modulaires sans utiliser de framework 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\/fr\/blog\/composants-web\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Une introduction compl\u00e8te aux composants web en 2026\" \/>\n<meta property=\"og:description\" content=\"Les composants web sont un moyen standard de cr\u00e9er des \u00e9l\u00e9ments HTML r\u00e9utilisables et modulaires sans utiliser de framework JavaScript.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/\" \/>\n<meta property=\"og:site_name\" content=\"Kinsta\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/kinstafrance\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-08-26T09:44:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-11-10T11:46:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/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=\"Les composants web sont un moyen standard de cr\u00e9er des \u00e9l\u00e9ments HTML r\u00e9utilisables et modulaires sans utiliser de framework JavaScript.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png\" \/>\n<meta name=\"twitter:creator\" content=\"@craigbuckler\" \/>\n<meta name=\"twitter:site\" content=\"@kinsta_fr\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"Craig Buckler\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/\"},\"author\":{\"name\":\"Craig Buckler\",\"@id\":\"https:\/\/kinsta.com\/fr\/#\/schema\/person\/715d986404b06691ab3014e06596908e\"},\"headline\":\"Une introduction compl\u00e8te aux composants web en 2026\",\"datePublished\":\"2021-08-26T09:44:25+00:00\",\"dateModified\":\"2023-11-10T11:46:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/\"},\"wordCount\":3472,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/fr\/#organization\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png\",\"keywords\":[\"html\",\"JavaScript\"],\"articleSection\":[\"D\u00e9veloppement web\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/\",\"url\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/\",\"name\":\"Une introduction compl\u00e8te aux composants web en 2026\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/fr\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png\",\"datePublished\":\"2021-08-26T09:44:25+00:00\",\"dateModified\":\"2023-11-10T11:46:09+00:00\",\"description\":\"Les composants web sont un moyen standard de cr\u00e9er des \u00e9l\u00e9ments HTML r\u00e9utilisables et modulaires sans utiliser de framework JavaScript.\",\"breadcrumb\":{\"@id\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#primaryimage\",\"url\":\"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png\",\"contentUrl\":\"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png\",\"width\":1460,\"height\":730},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/kinsta.com\/fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Outils de d\u00e9veloppement web\",\"item\":\"https:\/\/kinsta.com\/fr\/sujets\/outils-developpement-web\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Une introduction compl\u00e8te aux composants web en 2024\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kinsta.com\/fr\/#website\",\"url\":\"https:\/\/kinsta.com\/fr\/\",\"name\":\"Kinsta\u00ae\",\"description\":\"Solutions d&#039;h\u00e9bergement premium, rapides et s\u00e9curis\u00e9es\",\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kinsta.com\/fr\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kinsta.com\/fr\/#organization\",\"name\":\"Kinsta\",\"url\":\"https:\/\/kinsta.com\/fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/kinsta.com\/fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2023\/12\/kinsta-logo.jpeg\",\"contentUrl\":\"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2023\/12\/kinsta-logo.jpeg\",\"width\":500,\"height\":500,\"caption\":\"Kinsta\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/fr\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/kinstafrance\/\",\"https:\/\/x.com\/kinsta_fr\",\"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\/fr\/#\/schema\/person\/715d986404b06691ab3014e06596908e\",\"name\":\"Craig Buckler\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/kinsta.com\/fr\/#\/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\/fr\/blog\/author\/craigbuckler\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Une introduction compl\u00e8te aux composants web en 2026","description":"Les composants web sont un moyen standard de cr\u00e9er des \u00e9l\u00e9ments HTML r\u00e9utilisables et modulaires sans utiliser de framework 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\/fr\/blog\/composants-web\/","og_locale":"fr_FR","og_type":"article","og_title":"Une introduction compl\u00e8te aux composants web en 2026","og_description":"Les composants web sont un moyen standard de cr\u00e9er des \u00e9l\u00e9ments HTML r\u00e9utilisables et modulaires sans utiliser de framework JavaScript.","og_url":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/","og_site_name":"Kinsta\u00ae","article_publisher":"https:\/\/www.facebook.com\/kinstafrance\/","article_published_time":"2021-08-26T09:44:25+00:00","article_modified_time":"2023-11-10T11:46:09+00:00","og_image":[{"width":1460,"height":730,"url":"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png","type":"image\/png"}],"author":"Craig Buckler","twitter_card":"summary_large_image","twitter_description":"Les composants web sont un moyen standard de cr\u00e9er des \u00e9l\u00e9ments HTML r\u00e9utilisables et modulaires sans utiliser de framework JavaScript.","twitter_image":"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png","twitter_creator":"@craigbuckler","twitter_site":"@kinsta_fr","twitter_misc":{"\u00c9crit par":"Craig Buckler","Dur\u00e9e de lecture estim\u00e9e":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#article","isPartOf":{"@id":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/"},"author":{"name":"Craig Buckler","@id":"https:\/\/kinsta.com\/fr\/#\/schema\/person\/715d986404b06691ab3014e06596908e"},"headline":"Une introduction compl\u00e8te aux composants web en 2026","datePublished":"2021-08-26T09:44:25+00:00","dateModified":"2023-11-10T11:46:09+00:00","mainEntityOfPage":{"@id":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/"},"wordCount":3472,"commentCount":0,"publisher":{"@id":"https:\/\/kinsta.com\/fr\/#organization"},"image":{"@id":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png","keywords":["html","JavaScript"],"articleSection":["D\u00e9veloppement web"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/kinsta.com\/fr\/blog\/composants-web\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/","url":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/","name":"Une introduction compl\u00e8te aux composants web en 2026","isPartOf":{"@id":"https:\/\/kinsta.com\/fr\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#primaryimage"},"image":{"@id":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png","datePublished":"2021-08-26T09:44:25+00:00","dateModified":"2023-11-10T11:46:09+00:00","description":"Les composants web sont un moyen standard de cr\u00e9er des \u00e9l\u00e9ments HTML r\u00e9utilisables et modulaires sans utiliser de framework JavaScript.","breadcrumb":{"@id":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kinsta.com\/fr\/blog\/composants-web\/"]}]},{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#primaryimage","url":"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png","contentUrl":"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2021\/08\/web-components.png","width":1460,"height":730},{"@type":"BreadcrumbList","@id":"https:\/\/kinsta.com\/fr\/blog\/composants-web\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kinsta.com\/fr\/"},{"@type":"ListItem","position":2,"name":"Outils de d\u00e9veloppement web","item":"https:\/\/kinsta.com\/fr\/sujets\/outils-developpement-web\/"},{"@type":"ListItem","position":3,"name":"Une introduction compl\u00e8te aux composants web en 2024"}]},{"@type":"WebSite","@id":"https:\/\/kinsta.com\/fr\/#website","url":"https:\/\/kinsta.com\/fr\/","name":"Kinsta\u00ae","description":"Solutions d&#039;h\u00e9bergement premium, rapides et s\u00e9curis\u00e9es","publisher":{"@id":"https:\/\/kinsta.com\/fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kinsta.com\/fr\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/kinsta.com\/fr\/#organization","name":"Kinsta","url":"https:\/\/kinsta.com\/fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/kinsta.com\/fr\/#\/schema\/logo\/image\/","url":"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2023\/12\/kinsta-logo.jpeg","contentUrl":"https:\/\/kinsta.com\/fr\/wp-content\/uploads\/sites\/4\/2023\/12\/kinsta-logo.jpeg","width":500,"height":500,"caption":"Kinsta"},"image":{"@id":"https:\/\/kinsta.com\/fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/kinstafrance\/","https:\/\/x.com\/kinsta_fr","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\/fr\/#\/schema\/person\/715d986404b06691ab3014e06596908e","name":"Craig Buckler","image":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/kinsta.com\/fr\/#\/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\/fr\/blog\/author\/craigbuckler\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/posts\/48058","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/users\/188"}],"replies":[{"embeddable":true,"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/comments?post=48058"}],"version-history":[{"count":14,"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/posts\/48058\/revisions"}],"predecessor-version":[{"id":71428,"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/posts\/48058\/revisions\/71428"}],"alternate":[{"embeddable":true,"hreflang":"en","title":"English","href":"https:\/\/kinsta.com\/fr\/wp-json\/kinsta\/v1\/posts\/48058\/translations\/en"},{"embeddable":true,"hreflang":"fr","title":"French","href":"https:\/\/kinsta.com\/fr\/wp-json\/kinsta\/v1\/posts\/48058\/translations\/fr"},{"embeddable":true,"hreflang":"de","title":"German","href":"https:\/\/kinsta.com\/fr\/wp-json\/kinsta\/v1\/posts\/48058\/translations\/de"},{"embeddable":true,"hreflang":"es","title":"Spanish","href":"https:\/\/kinsta.com\/fr\/wp-json\/kinsta\/v1\/posts\/48058\/translations\/es"},{"embeddable":true,"hreflang":"it","title":"Italian","href":"https:\/\/kinsta.com\/fr\/wp-json\/kinsta\/v1\/posts\/48058\/translations\/it"},{"embeddable":true,"hreflang":"pt","title":"Portuguese","href":"https:\/\/kinsta.com\/fr\/wp-json\/kinsta\/v1\/posts\/48058\/translations\/pt"},{"embeddable":true,"hreflang":"nl","title":"Dutch","href":"https:\/\/kinsta.com\/fr\/wp-json\/kinsta\/v1\/posts\/48058\/translations\/nl"},{"embeddable":true,"hreflang":"sv","title":"Swedish","href":"https:\/\/kinsta.com\/fr\/wp-json\/kinsta\/v1\/posts\/48058\/translations\/se"},{"embeddable":true,"hreflang":"ja","title":"Japanese","href":"https:\/\/kinsta.com\/fr\/wp-json\/kinsta\/v1\/posts\/48058\/translations\/jp"},{"href":"https:\/\/kinsta.com\/fr\/wp-json\/kinsta\/v1\/posts\/48058\/tree"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/media\/48067"}],"wp:attachment":[{"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/media?parent=48058"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/tags?post=48058"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/kinsta.com\/fr\/wp-json\/wp\/v2\/topic?post=48058"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}