Customize embedded UI and render props
Control embedded menus and add host-application UI around the editor.
Customize the embedded editor by combining UIOptions, child components, and render props. Use UIOptions to hide or configure built-in actions, children to replace or extend visible regions, and render props to inject UI or replace embeddable rendering.
Before you begin
You need a React application with an Excalidraw component in a container with non-zero dimensions. Import child components from @excalidraw/excalidraw and keep controls accessible with visible text and keyboard focus.
Configure the built-in actions
Pass UIOptions.canvasActions to control actions such as background color, clear canvas, load, save, theme toggle, and save as image.
const UIOptions = {
canvasActions: {
changeViewBackgroundColor: false,
clearCanvas: false,
loadScene: false,
export: { saveFileToDisk: true },
},
};The configured actions are hidden or shown in the menu, while unspecified options retain their defaults.
Render supported children inside Excalidraw when you need a custom main menu, sidebar, footer, welcome screen, or collaboration trigger.
import {
Excalidraw,
Footer,
MainMenu,
Sidebar,
WelcomeScreen,
} from "@excalidraw/excalidraw";
<Excalidraw>
<MainMenu />
<Sidebar name="custom" />
<Footer />
<WelcomeScreen />
</Excalidraw>The children render in the editor’s supported extension points.
Use renderTopRightUI for a host action. The callback receives isMobile and the current appState.
<Excalidraw
renderTopRightUI={(isMobile, appState) => (
<button type="button" onClick={() => saveScene(appState)}>
Save draft
</button>
)}
/>The labeled button appears in the top-right area and remains usable without relying on color or position alone.
Render LiveCollaborationTrigger from renderTopRightUI when you provide the collaboration dialog yourself. Its required onSelect handler opens that dialog, and isCollaborating changes the button state.
<Excalidraw
isCollaborating={isCollaborating}
renderTopRightUI={() => (
<LiveCollaborationTrigger
isCollaborating={isCollaborating}
onSelect={() => setCollaborationOpen(true)}
/>
)}
renderCustomStats={() => <p>{elementCount} elements</p>}
/>The collaboration control can show the collaborator count from appState.collaborators; the stats dialog includes your additional JSX.
Replace embeddable rendering
Use renderEmbeddable when the default iframe is not suitable. The callback receives the embeddable element and current appState, and returns JSX or null.
<Excalidraw
renderEmbeddable={(element, appState) => (
<div aria-label="Embedded content">
{element.link}
</div>
)}
/>Keep URL validation separate with the validateEmbeddable prop when your application accepts web embeds.
Troubleshoot common failures
Next steps
Use the ExcalidrawAPI reference to update scenes and libraries from these controls.