DOM API
The DOM API provides access to pre-created DOM elements that Epos sets up for your project. These elements are useful for rendering content on web pages with proper isolation.
epos.dom.root
The project's root container element. This is a <div> that serves as the main container for all your project's DOM elements.
epos.dom.root: HTMLDivElementAttributes
data-project-name- The name of your projectdata-project-id- The unique identifier of your project
Example
// Access the root element
console.log(epos.dom.root)
// Append custom elements
const customElement = document.createElement('div')
customElement.textContent = 'Hello World'
epos.dom.root.appendChild(customElement)epos.dom.reactRoot
A pre-created element for React rendering outside of shadow DOM. This is used when you don't need style isolation.
epos.dom.reactRoot: HTMLDivElementAttributes
data-react-root- Marks this as a React root container
Example
// Manual React rendering (usually epos.render() does this automatically)
import { createRoot } from 'react-dom/client'
const root = createRoot(epos.dom.reactRoot)
root.render(<App />)epos.dom.shadowRoot
A pre-created shadow DOM root for style isolation. Use this when you want to prevent your styles from affecting the host page and vice versa.
epos.dom.shadowRoot: ShadowRootExample
// Append elements to shadow DOM
const element = document.createElement('div')
element.textContent = 'Isolated content'
epos.dom.shadowRoot.appendChild(element)
// Add styles that won't leak to the page
const style = document.createElement('style')
style.textContent = 'div { color: red; }'
epos.dom.shadowRoot.appendChild(style)epos.dom.shadowReactRoot
A pre-created element inside the shadow DOM specifically for React rendering. This is used when you have shadow CSS defined in your project.
epos.dom.shadowReactRoot: HTMLDivElementAttributes
data-react-root- Marks this as a React root container
Example
// React rendering in shadow DOM (usually epos.render() does this automatically)
import { createRoot } from 'react-dom/client'
const root = createRoot(epos.dom.shadowReactRoot)
root.render(<App />)DOM Hierarchy
The DOM structure that Epos creates looks like this:
<epos>
<div data-project-name="my-project" data-project-id="abc123">
<!-- epos.dom.root -->
<div data-react-root="">
<!-- epos.dom.reactRoot -->
<!-- React content renders here (if no shadow CSS) -->
</div>
<div data-shadow="">
#shadow-root
<!-- epos.dom.shadowRoot -->
<link rel="stylesheet" href="blob:..." />
<!-- Your shadow CSS -->
<div data-react-root="">
<!-- epos.dom.shadowReactRoot -->
<!-- React content renders here (if shadow CSS exists) -->
</div>
</div>
</div>
</epos>Shadow CSS Configuration
When you define shadow CSS in your epos.json, Epos automatically:
- Creates a shadow DOM with
epos.dom.shadowRoot - Injects your CSS as a linked stylesheet
- Uses
epos.dom.shadowReactRootfor React rendering - Hoists
@propertyrules to the document root (they don't work in shadow DOM)
TIP
Use epos.render() instead of accessing these elements directly. It automatically selects the correct root based on your project configuration.
Use Cases
Manual DOM Manipulation
// Add a custom element
const banner = document.createElement('div')
banner.className = 'my-banner'
banner.textContent = 'Extension loaded'
epos.dom.root.appendChild(banner)Style Isolation
// Add isolated styles
const style = document.createElement('style')
style.textContent = `
.my-widget {
color: blue;
font-size: 16px;
}
`
epos.dom.shadowRoot.appendChild(style)
// Add widget
const widget = document.createElement('div')
widget.className = 'my-widget'
widget.textContent = 'This style is isolated'
epos.dom.shadowRoot.appendChild(widget)Custom React Root
// Create a custom portal
import { createPortal } from 'react-dom'
const MyPortal = ({ children }) => {
return createPortal(children, epos.dom.shadowRoot)
}