Documentation Index
Fetch the complete documentation index at: https://mintlify.com/betterdiscord/betterdiscord/llms.txt
Use this file to discover all available pages before exploring further.
BdApi.ReactUtils provides utilities for interacting with Discord’s React internals. This is extremely useful for accessing component instances, wrapping elements, and working with React fibers.
Methods
getInternalInstance
Gets the internal React fiber data of a specified DOM node.
BdApi.ReactUtils.getInternalInstance(
node: HTMLElement
): Fiber | null
DOM node to get the internal React data from
Returns the React fiber object or null if not found.
const element = document.querySelector('.message');
const fiber = BdApi.ReactUtils.getInternalInstance(element);
console.log(fiber);
getOwnerInstance
Attempts to find the “owner” React instance of a DOM node. This is generally a component with a stateNode (class component).
BdApi.ReactUtils.getOwnerInstance(
node: HTMLElement | undefined,
options?: {
include?: string[],
exclude?: string[],
filter?: (owner: any) => boolean
}
): object | null
Node to obtain React instance of
List of component names to include in the search. When provided, only these components are considered.
List of component names to exclude from the search
options.filter
function
default:"() => true"
Filter function to check the current instance. Should return true to accept the instance.
Returns the owner instance or null if not found.
// Find any owner instance
const element = document.querySelector('.message');
const instance = BdApi.ReactUtils.getOwnerInstance(element);
// Find specific component
const messageComponent = BdApi.ReactUtils.getOwnerInstance(element, {
include: ["Message"]
});
// Find with custom filter
const filteredInstance = BdApi.ReactUtils.getOwnerInstance(element, {
filter: (owner) => owner.props?.id === "target-id"
});
wrapElement
Creates an unrendered React component that wraps HTML elements.
BdApi.ReactUtils.wrapElement(
element: HTMLElement | HTMLElement[]
): React.ComponentType
element
HTMLElement | HTMLElement[]
required
Element or array of elements to wrap
Returns an unrendered React component class.
const customDiv = document.createElement('div');
customDiv.textContent = 'Hello from HTML';
const WrappedComponent = BdApi.ReactUtils.wrapElement(customDiv);
// Use in React
const element = BdApi.React.createElement(WrappedComponent);
wrapInHooks
Wraps a React function component to intercept and mock React hooks. Useful for rendering components outside their normal context.
BdApi.ReactUtils.wrapInHooks<T>(
functionComponent: React.FunctionComponent<T>,
customPatches?: Partial<PatchedReactHooks>
): React.FunctionComponent<T>
functionComponent
React.FunctionComponent
required
The function component to wrap. Can be a plain function component, memo component, or forward ref component.
Optional custom implementations for specific hooks to override the default mocked behavior
// Get a Discord component that uses hooks
const UserPopout = BdApi.Webpack.getByKeys("UserPopoutBody");
// Wrap it to bypass hook requirements
const WrappedPopout = BdApi.ReactUtils.wrapInHooks(
UserPopout.UserPopoutBody
);
// Now you can render it outside its normal context
const element = BdApi.React.createElement(WrappedPopout, {user});
Custom hook patches
const WrappedComponent = BdApi.ReactUtils.wrapInHooks(
SomeComponent,
{
useState: (initial) => {
// Custom useState implementation
return [customValue, customSetter];
},
useEffect: () => {
// Custom useEffect implementation
console.log('Effect would run here');
}
}
);
getType
Unwraps React exotic components (memo, forwardRef, lazy) to get the underlying component.
BdApi.ReactUtils.getType<T>(
elementType: React.ElementType<T>
): T
elementType
React.ElementType
required
The component to unwrap. Can be a memo component, forwardRef, or lazy component.
Returns the underlying component function or class.
const MemoizedComponent = React.memo(MyComponent);
const unwrapped = BdApi.ReactUtils.getType(MemoizedComponent);
// unwrapped === MyComponent
const ForwardedComponent = React.forwardRef(MyComponent);
const unwrapped2 = BdApi.ReactUtils.getType(ForwardedComponent);
// unwrapped2 === MyComponent
createNodePatcher
Creates a new node patcher instance for patching React render methods.
BdApi.ReactUtils.createNodePatcher(): NodePatcher
Returns a new NodePatcher instance.
const patcher = BdApi.ReactUtils.createNodePatcher();
const fakeNode = {type: SomeComponent};
patcher.patch(fakeNode, (props, node, instance) => {
// Modify the render output
console.log('Component rendered with props:', props);
return node;
});
Usage examples
Finding a message component instance
// Right-click on a message to get its element
const messageElement = document.querySelector('[id^="chat-messages-"]');
// Get the Message component instance
const messageInstance = BdApi.ReactUtils.getOwnerInstance(messageElement, {
include: ["Message", "MessageContent"]
});
console.log(messageInstance.props);
Wrapping HTML in React
const customElement = document.createElement('div');
customElement.innerHTML = '<strong>Custom Content</strong>';
customElement.style.color = 'red';
const WrappedComponent = BdApi.ReactUtils.wrapElement(customElement);
// Inject into Discord UI
BdApi.ReactDOM.render(
BdApi.React.createElement(WrappedComponent),
document.querySelector('#app-mount')
);
Rendering a hooked component safely
// Get a component that uses context or hooks
const UserInfo = BdApi.Webpack.getByDisplayName("UserInfo");
// Wrap it to provide mock hooks
const SafeUserInfo = BdApi.ReactUtils.wrapInHooks(UserInfo, {
useContext: (context) => {
// Provide mock context value
return {userId: "123456789"};
}
});
// Render safely
const element = BdApi.React.createElement(SafeUserInfo);