Publicado em: 9 de março de 2026
Os elementos personalizados permitem que os desenvolvedores de apps da Web criem, compartilhem e reutilizem componentes de interface com comportamentos exclusivos, facilitando o desenvolvimento. Mas quando o app reúne diferentes conjuntos de elementos personalizados, as coisas podem ficar confusas, e podem ocorrer colisões de nomes. Registros de elementos personalizados com escopo resolvem esse problema.
A equipe do Microsoft Edge trabalhou nesse recurso, e temos o prazer de anunciar que os registros de elementos personalizados com escopo agora estão disponíveis por padrão no Edge e no Chrome 146, além de outros navegadores baseados no Chromium. Agora é possível encapsular elementos personalizados, resolvendo um problema antigo para desenvolvedores de componentes e bibliotecas de microfront-end.
Registros de elementos personalizados com escopo desbloqueiam padrões importantes para desenvolvedores da Web. Agora, você pode usar várias bibliotecas de elementos personalizados, desenvolvidas de forma independente por várias equipes, ou várias versões da mesma biblioteca lado a lado.

O que é um registro de elemento personalizado com escopo?
Hoje, cada definição de elemento personalizado em uma página da Web fica em um único
registro compartilhado em window.customElements. Isso significa que, se duas bibliotecas diferentes
tentarem definir um elemento personalizado com o mesmo nome de tag, como <my-button>,
um erro será gerado e a página será interrompida. Esse é um problema significativo no mundo real. Grandes aplicativos que compõem as interfaces de usuário de
várias equipes, sistemas de design ou microfrontends podem facilmente entrar em conflitos
de nomenclatura. Os registros de elementos personalizados com escopo resolvem isso permitindo que você crie registros independentes. Cada registro mantém seu próprio conjunto de definições de
elementos personalizados, completamente isolado do registro global e entre si.
Criar um registro
Em vez de definir todos os elementos personalizados no registro global window.customElements:
- Crie um novo registro chamando
new CustomElementRegistry(). - Dê ao novo registro um escopo específico (consulte "Definir o escopo do registro").
- Defina os elementos que vão para o novo registro.
Em seguida, quando um elemento personalizado é usado, o navegador procura a definição do elemento no registro associado, que não é necessariamente o global. Isso significa que diferentes partes da sua página podem usar conjuntos totalmente diferentes de definições de elementos personalizados.
Definir o escopo do registro
Um registro de elemento personalizado pode ser limitado a um documento, uma raiz de sombra ou um elemento individual.
Escopo para uma raiz shadow
Para definir o escopo de um novo registro para uma raiz shadow, use a opção customElementRegistry ao chamar o método attachShadow(). Todos os elementos personalizados dentro dessa raiz de sombra agora vão usar
a definição que está no registro de escopo correspondente:
// Create your custom registry.
const registry = new CustomElementRegistry();
// Define a custom element in the new registry.
registry.define('my-card', class extends HTMLElement {
connectedCallback() {
this.textContent = 'Hello from scoped registry!';
}
});
// Create shadow root, providing it with your new custom element registry.
const host = document.querySelector('#host');
const shadow = host.attachShadow({
mode: 'open',
customElementRegistry: registry,
});
shadow.innerHTML = '<my-card></my-card>';
Shadow DOM declarativo
Use o atributo
shadowrootcustomelementregistry
em um elemento <template> para informar ao navegador que a raiz
de sombra resultante está usando um registro com escopo em vez do global:
<my-host>
<template shadowrootmode="open" shadowrootcustomelementregistry>
<my-widget></my-widget>
</template>
</my-host>
const registry = new CustomElementRegistry();
registry.define('my-widget', class extends HTMLElement {
connectedCallback() { this.textContent = 'Scoped!'; }
});
const shadow = document.querySelector('my-host').shadowRoot;
registry.initialize(shadow);
Como mostrado no exemplo, o atributo reserva espaço para o registro de elementos personalizados, e o usuário precisa definir e inicializar o registro para o escopo da raiz shadow em um documento desconectado.
Também é possível definir o escopo de um registro para um documento, como um criado pelo
document.implementation.createHTMLDocument(). Isso permite clonar elementos
<template> e fazer manipulação de documentos fora da tela, cada um com
seus próprios conjuntos isolados de definições de componentes. Para fazer isso, use o método
CustomElementRegistry.initialize():
// Create a new registry.
const registry = new CustomElementRegistry();
registry.define('app-widget', AppWidget);
// Create a document, and use registry.initialize() to scope the registry to the document.
const doc = document.implementation.createHTMLDocument('');
registry.initialize(doc);
doc.body.innerHTML = '<app-widget></app-widget>';
Escopo para um elemento individual
Você também pode associar um registro diretamente a um elemento e à subárvore dele
transmitindo a opção customElementRegistry para document.createElement(). O elemento e seus descendentes serão resolvidos em relação a esse registro, não importa em qual parte do DOM eles sejam inseridos posteriormente:
// Create a registry and define a custom element in it.
const registry = new CustomElementRegistry();
registry.define('fancy-label', FancyLabel);
// Create a new DOM element and scope the new registry to it.
const el = document.createElement('fancy-input', {
customElementRegistry: registry,
});
// Use a custom element in the new DOM element.
el.innerHTML = '<fancy-label>Name</fancy-label>';
Saiba mais
Para saber mais, confira a demonstração do Edge e o código-fonte. Leia também o artigo de referência do CustomElementRegistry da MDN.
Os registros de elementos personalizados com escopo agora estão ativados por padrão no Microsoft Edge e no Chrome, bem como em outros navegadores baseados no Chromium, graças à nossa colaboração no projeto Chromium.
Não é necessário ativar nenhuma configuração nem se inscrever em um teste de origem. Você já pode começar a usar o recurso hoje mesmo em navegadores baseados no Chromium.
Se você precisar que esse recurso seja implementado em outros navegadores, dê um gostei no problema de registros de elementos personalizados com escopo e deixe um comentário com seus casos de uso e soluções alternativas.
Se você encontrar um bug na implementação do recurso em um navegador baseado no Chromium, abra um problema para que possamos investigar em crbug.com/new.
Esperamos que os registros de elementos personalizados com escopo facilitem o uso de componentes da Web.