Skip to main content

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.

UI element components provide the building blocks for creating custom interfaces in BetterDiscord plugins. These components offer consistent styling and behavior across Discord’s UI.

Text

A text component with color and size variants.
children
ReactNode
Text content to display
tag
string
default:"'div'"
HTML element type to render (e.g., "span", "p", "h1")
color
string
default:"Text.Colors.STANDARD"
Text color variant. Available colors:
  • Text.Colors.STANDARD - Standard text color
  • Text.Colors.MUTED - Muted/secondary text
  • Text.Colors.ERROR - Error/danger color
  • Text.Colors.BRAND - Brand color
  • Text.Colors.LINK - Link color
  • Text.Colors.HEADER_PRIMARY - Primary header color
  • Text.Colors.HEADER_SECONDARY - Secondary header color
  • Text.Colors.STATUS_YELLOW - Yellow status color
  • Text.Colors.STATUS_GREEN - Green status color
  • Text.Colors.STATUS_RED - Red status color
  • Text.Colors.ALWAYS_WHITE - Always white text
  • Text.Colors.CUSTOM - No color class applied
size
string
default:"Text.Sizes.SIZE_14"
Text size variant. Available sizes:
  • Text.Sizes.SIZE_10 - 10px
  • Text.Sizes.SIZE_12 - 12px
  • Text.Sizes.SIZE_14 - 14px
  • Text.Sizes.SIZE_16 - 16px
  • Text.Sizes.SIZE_20 - 20px
  • Text.Sizes.SIZE_24 - 24px
  • Text.Sizes.SIZE_32 - 32px
selectable
boolean
default:"false"
Whether the text can be selected
strong
boolean
default:"false"
Whether to apply bold font weight
className
string
Additional CSS classes to apply
style
CSSProperties
Inline styles to apply

Usage

const {Text} = BdApi.Components;

function MyComponent() {
    return (
        <div>
            <Text
                tag="h1"
                color={Text.Colors.HEADER_PRIMARY}
                size={Text.Sizes.SIZE_24}
                strong
            >
                Welcome to my plugin
            </Text>

            <Text color={Text.Colors.MUTED} size={Text.Sizes.SIZE_12}>
                This is a description with muted text
            </Text>

            <Text color={Text.Colors.ERROR}>
                An error occurred!
            </Text>
        </div>
    );
}

Flex

A flexbox container component with alignment and direction utilities.
children
ReactNode
Child elements to layout
direction
string
default:"Flex.Direction.HORIZONTAL"
Flex direction. Available directions:
  • Flex.Direction.VERTICAL - Column layout
  • Flex.Direction.HORIZONTAL - Row layout
  • Flex.Direction.HORIZONTAL_REVERSE - Reversed row layout
justify
string
default:"Flex.Justify.START"
Justify content alignment. Available options:
  • Flex.Justify.START - Align to start
  • Flex.Justify.END - Align to end
  • Flex.Justify.CENTER - Center items
  • Flex.Justify.BETWEEN - Space between items
  • Flex.Justify.AROUND - Space around items
align
string
default:"Flex.Align.STRETCH"
Align items. Available options:
  • Flex.Align.START - Align to start
  • Flex.Align.END - Align to end
  • Flex.Align.CENTER - Center items
  • Flex.Align.STRETCH - Stretch items
  • Flex.Align.BASELINE - Align to baseline
wrap
string
default:"Flex.Wrap.NO_WRAP"
Flex wrap behavior. Available options:
  • Flex.Wrap.NO_WRAP - No wrapping
  • Flex.Wrap.WRAP - Wrap items
  • Flex.Wrap.WRAP_REVERSE - Wrap in reverse
shrink
number
default:"1"
Flex shrink factor
grow
number
default:"1"
Flex grow factor
basis
string
default:"'auto'"
Flex basis value
className
string
Additional CSS classes to apply
style
CSSProperties
Inline styles to apply
onClick
function
Click event handler

Usage

const {Flex, Text, Button} = BdApi.Components;

function MyComponent() {
    return (
        <Flex
            direction={Flex.Direction.VERTICAL}
            align={Flex.Align.CENTER}
            justify={Flex.Justify.CENTER}
            style={{padding: '20px'}}
        >
            <Text size={Text.Sizes.SIZE_20}>Centered Content</Text>
            <Button>Click Me</Button>
        </Flex>
    );
}
Horizontal layout with spacing:
<Flex
    direction={Flex.Direction.HORIZONTAL}
    justify={Flex.Justify.BETWEEN}
    align={Flex.Align.CENTER}
>
    <Text>Left</Text>
    <Text>Center</Text>
    <Button>Right</Button>
</Flex>

Flex.Child

A wrapper component that applies flex child styling.
const {Flex} = BdApi.Components;

<Flex>
    <Flex.Child>First child</Flex.Child>
    <Flex.Child>Second child</Flex.Child>
</Flex>

Button

A button component with multiple style variants, colors, and sizes.
children
ReactNode
Button content
onClick
function
Click event handler
look
string
default:"Button.Looks.FILLED"
Button style variant. Available looks:
  • Button.Looks.FILLED - Filled background
  • Button.Looks.OUTLINED - Outlined border
  • Button.Looks.LINK - Link-styled button
  • Button.Looks.BLANK - No styling
color
string
default:"Button.Colors.BRAND"
Button color. Available colors:
  • Button.Colors.BRAND - Brand color
  • Button.Colors.BLURPLE - Discord blurple
  • Button.Colors.RED - Red/danger
  • Button.Colors.GREEN - Green/success
  • Button.Colors.YELLOW - Yellow/warning
  • Button.Colors.PRIMARY - Primary color
  • Button.Colors.LINK - Link color
  • Button.Colors.WHITE - White
  • Button.Colors.TRANSPARENT - Transparent
  • Button.Colors.CUSTOM - No color class
size
string
default:"Button.Sizes.MEDIUM"
Button size. Available sizes:
  • Button.Sizes.NONE - No size styling
  • Button.Sizes.TINY - Tiny button
  • Button.Sizes.SMALL - Small button
  • Button.Sizes.MEDIUM - Medium button
  • Button.Sizes.LARGE - Large button
  • Button.Sizes.ICON - Icon button
type
string
default:"'button'"
HTML button type ("button", "submit", "reset")
disabled
boolean
default:"false"
Whether the button is disabled
grow
boolean
default:"true"
Whether the button should grow to fill available space
className
string
Additional CSS classes to apply
buttonRef
RefObject
React ref for the button element
onKeyDown
function
Keyboard event handler

Usage

const {Button} = BdApi.Components;

function MyComponent() {
    return (
        <div>
            <Button
                onClick={() => console.log('Clicked!')}
                color={Button.Colors.BRAND}
            >
                Primary Action
            </Button>

            <Button
                onClick={() => console.log('Delete')}
                color={Button.Colors.RED}
                look={Button.Looks.OUTLINED}
            >
                Delete
            </Button>

            <Button
                look={Button.Looks.LINK}
                size={Button.Sizes.SMALL}
            >
                Cancel
            </Button>
        </div>
    );
}
Icon button:
<Button
    size={Button.Sizes.ICON}
    look={Button.Looks.FILLED}
    color={Button.Colors.PRIMARY}
    onClick={() => console.log('Icon clicked')}
>
    <YourIconComponent size="24px" />
</Button>

Spinner

A loading spinner component with multiple animation types.
type
string
default:"Spinner.Type.WANDERING_CUBES"
Spinner animation type. Available types:
  • Spinner.Type.WANDERING_CUBES - Two wandering cubes
  • Spinner.Type.CHASING_DOTS - Chasing dots animation
  • Spinner.Type.PULSING_ELLIPSIS - Pulsing ellipsis (three dots)
  • Spinner.Type.SPINNING_CIRCLE - Spinning circle
  • Spinner.Type.SPINNING_CIRCLE_SIMPLE - Simple spinning circle
  • Spinner.Type.LOW_MOTION - Low motion variant (automatically used when reduced motion is enabled)
animated
boolean
default:"true"
Whether the spinner should animate
className
string
Additional CSS classes to apply
itemClassName
string
CSS classes to apply to the spinner’s motion items
aria-label
string
Accessibility label for screen readers

Usage

const {Spinner} = BdApi.Components;

function MyComponent() {
    const [loading, setLoading] = React.useState(true);

    if (loading) {
        return (
            <Spinner
                type={Spinner.Type.SPINNING_CIRCLE}
                aria-label="Loading content"
            />
        );
    }

    return <div>Content loaded!</div>;
}
Different spinner types:
// Wandering cubes (default)
<Spinner />

// Pulsing ellipsis
<Spinner type={Spinner.Type.PULSING_ELLIPSIS} />

// Spinning circle
<Spinner type={Spinner.Type.SPINNING_CIRCLE} />

// Simple spinning circle
<Spinner type={Spinner.Type.SPINNING_CIRCLE_SIMPLE} />

Tooltip

Discord’s tooltip component for displaying contextual information on hover.
BdApi.Components.Tooltip is Discord’s internal tooltip component. For creating tooltips programmatically, use BdApi.UI.createTooltip().
text
string | ReactNode
required
Tooltip content to display
children
function
required
A function that receives tooltip props and returns a single React element. The element must accept onMouseEnter, onMouseLeave, and onFocus props.
position
string
default:"'top'"
Tooltip position. Available positions:
  • "top" - Above the element
  • "bottom" - Below the element
  • "left" - To the left of the element
  • "right" - To the right of the element
color
string
default:"'primary'"
Tooltip color. Available colors:
  • "primary" - Primary color
  • "black" - Black tooltip
  • "grey" - Grey tooltip
  • "brand" - Brand color
  • "green" - Green tooltip
  • "red" - Red tooltip
  • "yellow" - Yellow tooltip
spacing
number
Spacing between tooltip and target element
hideOnClick
boolean
default:"true"
Whether to hide the tooltip when the element is clicked

Usage

const {Tooltip, Button} = BdApi.Components;

function MyComponent() {
    return (
        <Tooltip text="This button does something cool">
            {(props) => (
                <Button {...props}>
                    Hover me
                </Button>
            )}
        </Tooltip>
    );
}
With custom positioning and color:
<Tooltip
    text="Delete this item?"
    position="bottom"
    color="red"
>
    {(props) => (
        <Button {...props} color={Button.Colors.RED}>
            Delete
        </Button>
    )}
</Tooltip>
Multiple lines:
<Tooltip
    text={
        <div>
            <div>Line 1</div>
            <div>Line 2</div>
        </div>
    }
>
    {(props) => (
        <span {...props}>Hover for details</span>
    )}
</Tooltip>
The children function must return a single element that can accept DOM event props. If you need to wrap multiple elements, use a container element like div or span.

ErrorBoundary

A React error boundary component that catches errors in child components.
children
ReactNode
Child components to protect with error boundary
id
string
default:"'Unknown'"
Identifier for debugging purposes (appears in error logs)
name
string
default:"'Unknown'"
Name for debugging purposes (appears in error logs)
hideError
boolean
default:"false"
Whether to hide the default error message in the UI (never shown if a fallback is provided)
fallback
ReactNode
Custom fallback UI to display when an error occurs
onError
function
Callback function called when an error is caught. Receives the error object.

Usage

const {ErrorBoundary, Text} = BdApi.Components;

function MyPlugin() {
    return (
        <ErrorBoundary
            id="my-plugin-main"
            name="MyPlugin"
            onError={(error) => {
                console.error('MyPlugin error:', error);
                // Log to your error tracking service
            }}
        >
            <MyPluginContent />
        </ErrorBoundary>
    );
}
With custom fallback:
<ErrorBoundary
    id="settings-panel"
    name="Settings Panel"
    fallback={
        <Text color={Text.Colors.ERROR}>
            Failed to load settings. Please restart Discord.
        </Text>
    }
>
    <SettingsPanel />
</ErrorBoundary>
Hiding the default error message:
<ErrorBoundary
    id="custom-component"
    name="CustomComponent"
    hideError
    onError={(error) => {
        // Handle error silently
        BdApi.UI.showToast('An error occurred', {type: 'error'});
    }}
>
    <CustomComponent />
</ErrorBoundary>

Best practices

Component composition

Combine components to create rich interfaces:
const {Flex, Text, Button, Spinner} = BdApi.Components;

function LoadingButton({loading, children, onClick}) {
    return (
        <Button onClick={onClick} disabled={loading}>
            <Flex
                align={Flex.Align.CENTER}
                justify={Flex.Justify.CENTER}
                style={{gap: '8px'}}
            >
                {loading && <Spinner type={Spinner.Type.PULSING_ELLIPSIS} />}
                <Text>{children}</Text>
            </Flex>
        </Button>
    );
}

Consistent spacing

Use Flex containers for consistent spacing:
<Flex
    direction={Flex.Direction.VERTICAL}
    style={{gap: '16px', padding: '20px'}}
>
    <Text size={Text.Sizes.SIZE_20}>Title</Text>
    <Text color={Text.Colors.MUTED}>Description</Text>
    <Flex style={{gap: '8px'}}>
        <Button>Confirm</Button>
        <Button look={Button.Looks.OUTLINED}>Cancel</Button>
    </Flex>
</Flex>

Error handling

Always wrap major sections in ErrorBoundary:
function MyPlugin() {
    return (
        <ErrorBoundary id="my-plugin" name="MyPlugin">
            <Flex direction={Flex.Direction.VERTICAL}>
                <ErrorBoundary id="header" name="Header">
                    <Header />
                </ErrorBoundary>

                <ErrorBoundary id="content" name="Content">
                    <Content />
                </ErrorBoundary>

                <ErrorBoundary id="footer" name="Footer">
                    <Footer />
                </ErrorBoundary>
            </Flex>
        </ErrorBoundary>
    );
}