Repository: react
Issue: [React 19] Support scoped custom element registries (i.e, react with Custom Elements being rendered in a shadow root)
Labels: React 19

## Summary

**This is not an issue, but a (hopefully small) feature request/enhancement to the Custom Element support coming in React 19.**

The Custom Element support in React 19 is awesome! But even once React 19 lands, there will still be one challenge that Custom Element component library maintainers face. There is no way to inform React to use a scoped custom element registry when creating elements.

### Scoped Custom Element Registries

[Proppsal](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Scoped-Custom-Element-Registries.md)

The above proposal implements a new `CustomElementRegistry()` api where Custom Element authors can register custom elements to a registry that is not the global registry. An implementation of scoped custom element registries is in [Chrome Canary](https://chromestatus.com/feature/5090435261792256) under a flag at the moment, and the Web Components Community Group is working to see them implemented in all browsers.

There are also several polyfills that add this behavior to browsers in the meantime. Here is the one I use:

[Polyfill](https://github.com/webcomponents/polyfills/tree/master/packages/scoped-custom-element-registry)

### Use case: Micro-frontend application

Micro-frontend application architectures are very common. This pattern is where a host application will use module federation (webpack, vite etc) to dynamically fetch JS modules containing separate "remote applications" that the host app then assembles into a single seamless application for the user. The architecture is popular because it enables autonomy of releases between remote applications.

For Custom Elements though, the problem is that with only the single global Custom Element registry in browsers, remotes can't scope their Custom Elements efectively and so there can be version conflicts when remote applications depend on different version of the same custom element. Whichever version gets registered first "wins" and the other remotes break.

Scoped element registries solve this. If a remote application is rendered inside a shadow root (custom element, or just a div with an attached shadow root) then all Custom Element definitions in that remote can be pulled from a scoped registry instead of the global one. Bye bye version conflicts! Every remote gets its own version of the Custom Elements it uses.


### Feature Request
If the remote application uses a framework like React where `document.createElement` is used. In order to create a scoped Custom Element using the scoped definition in the custom registry, `shadowRoot.createElement()` is the mechanism.

React (and other frameworks also) have no way to be informed that they are being rendered inside a shadow root with a scoped registry attached. And therefore have no mechanism to switch from `document.createElement` to `shadowRoot.createElement`. React can already render inside a shadow root just fine. React's root can be an element inside a shadow root with no issues. This feature is about detecting whether or not React's render root has a parent element that is a shadow root and switching to `shadowRoot.createElement()` accordingly.

I hope this is enough detail to describe the ask. I would think that this might not be a huge feature or change to existing React fundamentals, but I'm not an expert on what the exact implementation approach should be. I'm just familiar with the current problem landscape and our workarounds that we use to get around it being cumbersome.

[This comment](https://github.com/WICG/webcomponents/issues/1043#issuecomment-1883480452) in a thread about the topic has a rough idea of what the implementation might look like.

I would think that with an implementation similar to the above, `document.createElement()` would be used in applications where there aren't any scoped element registry polyfills, or where the feature hasn't yet landed natively in browsers, so there may be low risk to a check for "is the root node in a shadow root".