> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Inject Extra Content in Widget

<Card title="Recommended: JavaScript SDK with React Hooks" icon="react" color="#4779FE">
  For new React apps, we recommend the JavaScript SDK with React Hooks (`@dynamic-labs-sdk/react-hooks`) instead of the legacy React SDK documented here. The JS SDK comes with many benefits such as a much smaller bundle size and other optimizations. Use the [React quickstart (JavaScript SDK)](/javascript/reference/react-quickstart) to get started.
</Card>

Should you want to add content to the widget (or indeed any of our UI components), since we use [a Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM) to ensure encapsulation of styling, you should first access the `shadowRoot` property of the host element - from there you can access the elements and manipulate them or append new ones.

For example, if you want to target the Dynamic Widget, you'd look for an element with `data-testid="dynamic-modal-shadow"`:

```javascript theme={"system"}
   const shadowHosts = document.querySelectorAll(
        '[data-testid="dynamic-modal-shadow"]'
    );
```

From there you'll need to pick the element that is the shadowRoot:

```javascript theme={"system"}
  shadowHosts.forEach((shadowHost) => {
    if (shadowHost && shadowHost.shadowRoot) {
      // Logic here
    }
  })
```

As a best practice, you can encapsulate your manipulation logic in a function, then call that function immediately but also add it to a mutation observer.

The observer is important for multiple reasons:

1. The widget content may change dynamically (e.g., different views or states).
2. The widget might be destroyed and recreated in the DOM.
3. Your custom content might be overwritten by internal widget updates.

```javascript theme={"system"}
    const injectButton = () => {
      // Logic to inject a new button into the widget
    }

    injectButton();

    const observer = new MutationObserver((mutations) => {
      injectButton();
    });

    observer.observe(shadowHost.shadowRoot, {
      childList: true,
      subtree: true,
    });
```

Now you have access to the modal, you can target whatever element you want to adjust, or append new elements at will.
