API Reference@liveblocks/react-ui

@liveblocks/react-ui provides you with React components to build collaborative experiences. Read our Comments and Notifications get started guides to learn more.

Comments

Default components

Thread

Displays a thread of comments. Each thread has a composer for creating replies.

<Thread thread={thread} />
Thread

Map through threads to render a list of the room’s threads and comments. Threads can be retrieved with useThreads.

import { Thread } from "@liveblocks/react-ui";import { useThreads } from "../liveblocks.config";
function Component() { const { threads } = useThreads();
return ( <> {threads.map((thread) => ( <Thread key={thread.id} thread={thread} /> ))} </> );}
Resolved and unresolved threads

A thread can be marked as resolved or unresolved via its resolved property. The Thread component automatically handles this through its resolved toggle button displayed by default.

You can additionally use thread.resolved to filter the displayed threads for example. Or if you want to create your own Thread component using the primitives, you can use useMarkThreadAsResolved and useMarkThreadAsUnresolved to update the property.

Props
  • threadThreadDataRequired

    The thread to display.

  • showComposerboolean | "collapsed"Default is "collapsed"

    How to show or hide the composer to reply to the thread.

  • showActionsboolean | "hover"Default is "hover"

    How to show or hide the actions.

  • showReactionsbooleanDefault is true

    Whether to show reactions.

  • showResolveActionbooleanDefault is true

    Whether to show the action to resolve the thread.

  • indentCommentContentbooleanDefault is true

    Whether to indent the comments’ content.

  • showDeletedCommentsbooleanDefault is false

    Whether to show deleted comments.

  • onResolvedChangefunction

    The event handler called when changing the resolved status.

  • onThreadDeletefunction

    The event handler called when the thread is deleted. A thread is deleted when all its comments are deleted.

  • onCommentEditfunction

    The event handler called when a comment is edited.

  • onCommentDeletefunction

    The event handler called when a comment is deleted.

  • onAuthorClickfunction

    The event handler called when clicking on a comment’s author.

  • onMentionClickfunction

    The event handler called when clicking on a mention.

  • overridesPartial<GlobalOverrides & ThreadOverrides & CommentOverrides & ComposerOverrides>

    Override the component’s strings.

Composer

Displays a composer for creating threads or comments.

<Composer />
Composer

By default, submitting the composer will create a new thread.

import { Composer } from "@liveblocks/react-ui";
// Creates a new threadfunction Component() { return <Composer />;}
Adding thread metadata

If you’d like to attach custom metadata to the newly created thread, you can add a metadata prop.

import { Composer } from "@liveblocks/react-ui";
// Creates a new thread with custom metadatafunction Component() { return ( <Composer metadata={{ // Custom metadata here, e.g. colors, coordinates color: "purple", x: 80, y: 120, }} /> );}
Typed metadata

Optionally, you can type metadata by importing your custom ThreadMetadata type from your config file.

import { Composer } from "@liveblocks/react-ui";import { ThreadMetadata } from "../liveblocks.config";
// Creates a new thread with custom metadatafunction Component() { return ( <Composer<ThreadMetadata> metadata={{ // Custom metadata with typing color: "purple", }} /> );}
liveblocks.config.ts
export type ThreadMetadata = {  color: string;};
Replying to a thread

If you provide a threadId, then submitting the composer will add a new reply to the thread.

import { Composer } from "@liveblocks/react-ui";
// Adds a new comment to a threadfunction Component({ threadId }) { return <Composer threadId={threadId} />;}
Modifying a comment

If you provide both a threadId and a commentId, then submitting the composer will edit the comment.

import { Composer } from "@liveblocks/react-ui";
// Edits an existing commentfunction Component({ threadId, commentId }) { return <Composer threadId={threadId} commentId={commentId} />;}
Custom behavior

If you’d like to customize submission behavior, you can use event.preventDefault() in onComposerSubmit to disable the default behavior and call comment and thread mutation methods manually.

import { Composer } from "@liveblocks/react-ui";import { useEditComment, useAddReaction } from "../liveblocks.config";
// Custom submission behavior (edits a comment and adds a reaction)function Component({ threadId, commentId }) { const editComment = useEditComment(); const addReaction = useAddReaction();
return ( <Composer onComposerSubmit={({ body }, event) => { event.preventDefault();
// Example mutations editComment({ threadId, commentId, body }); addReaction({ threadId, commentId, emoji: "✅" });
// Other custom behavior // ... }} /> );}

Learn more about mutation hooks under @liveblocks/react.

Props
  • threadIdstring

    The ID of the thread to reply to or to edit a comment in.

  • commentIdstring

    The ID of the comment to edit.

  • metadataThreadMetadata

    The metadata of the thread to create.

  • onComposerSubmitfunction

    The event handler called when the composer is submitted.

  • defaultValueCommentBody

    The composer’s initial value.

  • collapsedboolean

    Whether the composer is collapsed. Setting a value will make the composer controlled.

  • onCollapsedChangefunction

    The event handler called when the collapsed state of the composer changes.

  • defaultCollapsedboolean

    Whether the composer is initially collapsed. Setting a value will make the composer uncontrolled.

  • disabledboolean

    Whether the composer is disabled.

  • autoFocusboolean

    Whether to focus the composer on mount.

  • overridesPartial<GlobalOverrides & ComposerOverrides>

    Override the component’s strings.

Comment

Displays a single comment.

<Comment comment={comment} />
Comment

Map through thread.comments to render each comment in a thread. Threads can be retrieved with useThreads.

import { Comment } from "@liveblocks/react-ui";import { ThreadData } from "@liveblocks/client";
// Renders a list of comments attach to the specified `thread`function Component({ thread }: { thread: ThreadData }) { return ( <> {thread.comments.map((comment) => ( <Comment key={comment.id} comment={comment} /> ))} </> );}
Custom thread components

Comment can be used in combination with Composer to create a custom thread component. The composer in this example is used to reply to the existing thread.

import { Comment, Composer } from "@liveblocks/react-ui";import { ThreadData } from "@liveblocks/client";import { useThreads } from "../liveblocks.config";
// Renders a list of comments and a composer for adding new commentsfunction CustomThread({ thread }: { thread: ThreadData }) { return ( <> {thread.comments.map((comment) => ( <Comment key={comment.id} comment={comment} /> ))} <Composer threadId={thread.id} /> </> );}
// Renders a list of custom thread componentsfunction Component() { const { threads } = useThreads();
return ( <> {threads.map((thread) => ( <CustomThread key={thread.id} /> ))} </> );}
Props
  • commentCommentDataRequired

    The comment to display.

  • showActionsboolean | "hover"Default is "hover"

    How to show or hide the actions.

  • showReactionsbooleanDefault is true

    Whether to show reactions.

  • indentContentbooleanDefault is true

    Whether to indent the comment’s content.

  • showDeletedbooleanDefault is false

    Whether to show the comment if it was deleted. If set to false, it will render deleted comments as null.

  • onCommentEditfunction

    The event handler called when the comment is edited.

  • onCommentDeletefunction

    The event handler called when the comment is deleted.

  • onAuthorClickfunction

    The event handler called when clicking on the author.

  • onMentionClickfunction

    The event handler called when clicking on a mention.

  • overridesPartial<GlobalOverrides & CommentOverrides & ComposerOverrides>

    Override the component’s strings.

Primitives

Primitives are unstyled, headless components that can be used to create fully custom commenting experiences.

Composition

All primitives are composable; they forward their props and refs, merge their classes and styles, and chain their event handlers.

Inspired by Radix (and powered by its Slot utility), most of the primitives also support an asChild prop to replace the rendered element by any provided child, and both set of props will be merged.

import { Button } from "@/my-design-system";
// Use the default <button> element<Composer.Submit disabled>Send</Composer.Submit>;
// Use an existing custom <Button> component<Composer.Submit disabled asChild> <Button variant="primary">Send</Button></Composer.Submit>;

Learn more about this concept on Radix’s composition guide.

Composer

Used to render a composer for creating, or editing, threads and comments.

<Composer.Form>  <Composer.Editor    components={{      Mention: () => <Composer.Mention />,      MentionSuggestions: () => (        <Composer.Suggestions>          <Composer.SuggestionsList>            <Composer.SuggestionsListItem />          </Composer.SuggestionsList>        </Composer.Suggestions>      ),      Link: () => <Composer.Link />,    }}  />  <Composer.Submit /></Composer.Form>

Combine with useCreateThread to render a composer that creates threads.

import {  Composer,  CommentBodyLinkProps,  CommentBodyMentionProps,  ComposerEditorMentionSuggestionsProps,  ComposerSubmitComment,} from "@liveblocks/react-ui/primitives";import { useCreateThread, useUser } from "../liveblocks.config.ts";import { FormEvent } from "react";
// Render a custom composer that creates a thread on submitfunction MyComposer() { const createThread = useCreateThread();
function handleComposerSubmit( { body }: ComposerSubmitComment, event: FormEvent<HTMLFormElement> ) { event.preventdefault();
// Create a new thread const thread = createThread({ body, metadata: {}, }); }
return ( <Composer.Form onComposerSubmit={handleComposerSubmit}> <Composer.Editor components={{ Mention, MentionSuggestions, Link, }} /> <Composer.Submit>Create thread</Composer.Submit> </Composer.Form> );}
// Render a mention in the composer's editor, e.g. "@Emil Joyce"function Mention({ userId }: CommentBodyMentionProps) { return <Comment.Mention>@{userId}</Comment.Mention>;}
// Render a list of mention suggestions, used after typing "@" in the editorfunction MentionSuggestions({ userIds, selectedUserId,}: ComposerEditorMentionSuggestionsProps) { return ( <Composer.Suggestions> <Composer.SuggestionsList> {userIds.map((userId) => ( <MentionSuggestion key={userId} userId={userId} /> ))} </Composer.SuggestionsList> </Composer.Suggestions> );}
// Render a single mention suggestion from a `userId`function MentionSuggestion({ userId }: { userId: string }) { const { user } = useUser(userId);
return ( <Composer.SuggestionsListItem value={user.id}> <img src={user.avatar} alt={user.name} /> {user.name} </Composer.SuggestionsListItem> );}
// Render a link in the composer's editor, e.g. "https://liveblocks.io"function Link({ href, children }: CommentBodyLinkProps) { return <Comment.Link href={href}>{children}</Comment.Link>;}
Composer.Form

Surrounds the composer’s content and handles submissions. By default, no action occurs when the composer is submitted. You must create your own mutations within onComposerSubmit for creating threads, creating comments, editing comments, etc.

<Composer.Form onComposerSubmit={({ body }) => {}}>{/* ... */}</Composer.Form>
  • onComposerSubmitfunction

    The event handler called when the form is submitted.

  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

Composer.Editor

Displays the composer’s editor.

<Composer.Editor placeholder="Write a comment…" />
  • defaultValueCommentBody

    The editor’s initial value.

  • placeholderstring

    The text to display when the editor is empty.

  • disabledboolean

    Whether the editor is disabled.

  • autoFocusboolean

    Whether to focus the editor on mount.

  • dir"ltr" | "rtl"

    The reading direction of the editor and related elements.

  • componentsPartial<ComposerEditorComponents>

    The components displayed within the editor.

AttributeValue
data-focusedPresent when the component is focused.
data-disabledPresent when the component is disabled.
components

The components displayed within the editor.

  • MentionComponentType<ComposerEditorMentionProps>

    The component used to display mentions. Defaults to the mention’s userId prefixed by an @.

  • MentionSuggestionsComponentType<ComposerEditorMentionSuggestionProps>

    The component used to display mention suggestions. Defaults to a list of the suggestions’ userId.

  • LinkComponentType<ComposerEditorLinkProps>

    The component used to display links. Defaults to the link’s children property.

Mention

The component used to display mentions.

<Composer.Editor  components={{    Mention: ({ userId, isSelected }) => (      <Composer.Mention>@{userId}</Composer.Mention>    ),  }}/>
  • userIdstring

    The mention’s user ID.

  • isSelectedboolean

    Whether the mention is selected.

MentionSuggestions

The component used to display mention suggestions.

  • userIdsstring[]

    The list of suggested user IDs.

  • selectedUserIdstring

    he currently selected user ID.

<Composer.Editor  components={{    MentionSuggestions: () => (      <Composer.Suggestions>        <Composer.SuggestionsList>          <Composer.SuggestionsListItem />        </Composer.SuggestionsList>      </Composer.Suggestions>    ),  }}/>
Link

The component used to display links.

<Composer.Editor  components={{    Link: ({ href, children }) => <Composer.Link>{children}</Composer.Link>,  }}/>
  • hrefstring

    The link’s absolute URL.

  • childrenReactNode

    The link’s content.

Composer.Mention

Displays mentions within Composer.Editor.

<Composer.Mention>@{userId}</Composer.Mention>
  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

AttributeValue
data-selectedPresent when the mention is selected.
Composer.Suggestions

Contains suggestions within Composer.Editor.

<Composer.Suggestions>{/* … */}<Composer.Suggestions>
  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

Composer.SuggestionsList

Displays a list of suggestions within Composer.Editor.

<Composer.SuggestionsList>  {userIds.map((userId) => (    <Composer.SuggestionsListItem key={userId} value={userId}>      @{userId}    </Composer.SuggestionsListItem>  ))}</Composer.SuggestionsList>
  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

Composer.SuggestionsListItem

Displays a suggestion within Composer.SuggestionsList.

<Composer.SuggestionsListItem key={userId} value={userId}>  @{userId}</Composer.SuggestionsListItem>
  • valuestringRequired

    The suggestion’s value.

  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

AttributeValue
data-selectedPresent when the item is selected.
Composer.Link

Displays links within Composer.Editor.

<Composer.Link href={href}>{children}</Composer.Link>
  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

Composer.Submit

A button to submit the composer.

<Composer.Submit>Send</Composer.Submit>
  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

Comment

Used to render a single comment.

<Comment.Body  components={{    Mention: <Comment.Mention />,    Link: <Comment.Link />,  }}/>

Map through thread.comments to render each comment in a thread. Threads can be retrieved with useThreads.

import {  Comment,  CommentBodyLinkProps,  CommentBodyMentionProps,} from "@liveblocks/react-ui/primitives";import { ThreadData } from "@liveblocks/client";
// Render custom comments in a thread. Pass a thread from `useThreads`.function MyComments({ thread }: { thread: ThreadData }) { return ( <> {thread.comments.map((comment) => ( <div key={comment.id}> <Comment.Body body={comment.body} components={{ Mention, Link, }} /> </div> ))} </> );}
// Render a mention in the comment, e.g. "@Emil Joyce"function Mention({ userId }: CommentBodyMentionProps) { return <Comment.Mention>@{userId}</Comment.Mention>;}
// Render a link in the comment, e.g. "https://liveblocks.io"function Link({ href, children }: CommentBodyLinkProps) { return <Comment.Link href={href}>{children}</Comment.Link>;}
Comment.Body

Displays a comment body.

<Comment.Body body={comment.body} />
  • bodyCommentBody

    The comment body to display. If not defined, the component will render null.

  • componentsPartial<CommentBodyComponents>

    The components displayed within the comment body.

  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

components

The components displayed within the comment body.

  • MentionComponentType<CommentBodyMentionProps>

    The component used to display mentions. Defaults to the mention’s userId prefixed by an @.

  • LinkComponentType<CommentBodyLinkProps>

    The component used to display links. Defaults to the link’s children property.

Mention

The component used to display mentions.

<Comment.Body  components={{    Mention: ({ userId }) => <Comment.Mention>@{userId}</Comment.Mention>,  }}/>
  • userIdstring

    The mention’s user ID.

Link

The component used to display links.

<Comment.Body  components={{    Link: ({ href, children }) => (      <Comment.Link href={href}>{children}</Comment.Link>    ),  }}/>
  • hrefstring

    The link’s absolute URL.

  • childrenReactNode

    The link’s content.

Comment.Mention

Displays mentions within Comment.Body.

<Comment.Mention>@{userId}</Comment.Mention>
  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

Comment.Link

Displays links within Comment.Body.

<Comment.Link href={href}>{children}</Comment.Link>
  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

Timestamp

Displays a formatted date, and automatically re-renders to support relative formatting. Defaults to relative formatting for recent dates (e.g. “5 minutes ago”) and a short absolute formatting for older ones (e.g. “25 Aug”).

<Timestamp date={new Date()} />

Use with comment.createdAt, comment.editedAt, or comment.deletedAt to display a human-readable time.

import { ThreadData, Timestamp } from "@liveblocks/react-ui";
function MyComments({ thread }: { thread: ThreadData }) { return ( <> {thread.comments.map((comment) => ( <div key={comment.id}> <Timestamp date={comment.createdAt} /> <Comment.Body body={comment.body} components={/* ... */} /> </div> ))} </> );}
  • dateDate | string | numberRequired

    The date to display.

  • childrenfunction

    A function to format the displayed date. Defaults to a relative date formatting function.

  • titlestring | function

    The title attribute’s value or a function to format it. Defaults to an absolute date formatting function.

  • intervalnumber | falseDefault is 30000

    The interval in milliseconds at which the component will re-render. Can be set to false to disable re-rendering.

  • localestring

    The locale used when formatting the date. Defaults to the browser’s locale.

  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

Hooks

useComposer

Returns states and methods related to the composer. Can only be used within the Composer.Form primitive.

import { useComposer } from "@liveblocks/react-ui/primitives";
const { isEmpty, submit } = useComposer();

This hook has a number of uses, for example constructing a custom button that submits threads, and disabling it when the composer input is empty.

import { Composer, useComposer } from "@liveblocks/react-ui/primitives";
function MyComposer() { return ( <Composer.Form onComposerSubmit={/* handle submit */}> <Composer.Editor components={/* Your custom component parts */} /> <MyComposerButton /> </Composer.Form> );}
// Button that submits the form, and is disabled when the input is emptyfunction MyComposerButton() { const { isEmpty, submit } = useComposer();
return ( <button onClick={submit} disabled={isEmpty}> Create thread </button> );}

Other hooks

Other Comments hooks are part of @liveblocks/react, you can find them on the React API reference page.

Notifications

Default components

InboxNotification

Displays a single inbox notification.

<InboxNotification inboxNotification={inboxNotification} />
InboxNotification

Map through inboxNotifications with useInboxNotifications to render a list of the room’s notifications.

import { InboxNotification } from "@liveblocks/react-ui";import { useInboxNotifications } from "../liveblocks.config";
function Component() { const { inboxNotifications } = useInboxNotifications();
return ( <> {inboxNotifications.map((inboxNotification) => ( <InboxNotification key={inboxNotification.id} inboxNotification={inboxNotification} /> ))} </> );}
Rendering notification kinds differently

Different kinds of notifications are available, for example thread which is triggered when using Comments, or $myCustomNotification which would be a custom notification you’ve triggered manually. You can choose to render each notification differently.

<InboxNotification  inboxNotification={inboxNotification}  kinds={{    thread: (props) => (      <InboxNotification.Thread {...props} showRoomName={false} />    ),    $myCustomNotification: (props) => (      <InboxNotification.Custom        {...props}        title="New notification"        aside={<InboxNotification.Icon></InboxNotification.Icon>}      >        My custom notification      </InboxNotification.Custom>    ),  }}/>

Adding these two properties to kinds will overwrite the default component that’s displayed for those two notification types. Using InboxNotification.Thread and InboxNotification.Custom in this way allow you to easily create components that fit into the existing design system, whilst still adding lots of customization. However, it’s also valid to render any custom JSX.

<InboxNotification  inboxNotification={inboxNotification}  kinds={{    $myCustomNotification: (props) => <div>New notification</div>,  }}/>
Typing custom notifications

To type custom notifications, edit the ActivitiesData type in your config file.

liveblocks.config.ts
declare global {  interface Liveblocks {    // Custom activities data for custom notification kinds    ActivitiesData: {      // Example, a custom $alert kind      $alert: {        title: string;        message: string;      };    };
// Other kinds // ... }}

Your activities data is now correctly typed in inline functions.

<InboxNotification  inboxNotification={inboxNotification}  kinds={{    $alert: (props) => {      // `title` and `message` are correctly typed, as defined in your config      const { title, message } = props.inboxNotification.activities[0].data;
return ( <InboxNotification.Custom {...props} title={title} aside={<InboxNotification.Icon></InboxNotification.Icon>} > {message} </InboxNotification.Custom> ); }, }}/>

If you’d like to create a typed function elsewhere, you can use InboxNotificationCustomProps with a generic. In the example below we’re using the $alert notification kind as a generic, InboxNotificationCustomKindProps<"$alert">.

import {  InboxNotification,  InboxNotificationCustomKindProps,} from "@liveblocks/react-ui";
function AlertNotification(props: InboxNotificationCustomKindProps<"$alert">) { // `title` and `message` are correctly typed, as defined in your config const { title, message } = props.inboxNotification.activities[0].data;
return ( <InboxNotification.Custom {...props} title={title} aside={<InboxNotification.Icon></InboxNotification.Icon>} > {message} </InboxNotification.Custom> );}
function Notification({ inboxNotification }) { return ( <InboxNotification inboxNotification={inboxNotification} kinds={{ $alert: AlertNotification }} /> );}
Props
  • inboxNotificationInboxNotificationDataRequired

    The inbox notification to display.

  • hrefstring

    The URL which the inbox notification links to.

  • showActionsboolean | "hover"

    How to show or hide the actions.

  • kindsPartial<InboxNotificationKinds>

    Override specific kinds of inbox notifications.

  • overridesPartial<GlobalOverrides & InboxNotificationOverrides & CommentOverrides>

    Override the component’s strings.

  • componentsPartial<GlobalComponents>

    Override the component’s components.

kinds

Override specific kinds of inbox notifications.

  • threadComponentType<InboxNotificationThreadKindProps>

    The component used to display thread notifications. Defaults to InboxNotification.Thread.

  • $${string}ComponentType<InboxNotificationCustomKindProps>

    The component used to display a custom notification kind. Custom notification kinds must start with a $.

InboxNotification.Thread

Displays a thread inbox notification.

<InboxNotification  inboxNotification={inboxNotification}  kinds={{    thread: (props) => (      <InboxNotification.Thread {...props} showRoomName={false} />    ),  }}/>
  • inboxNotificationInboxNotificationThreadDataRequired

    The inbox notification to display.

  • showActionsboolean | "hover"

    How to show or hide the actions.

  • showRoomNameboolean

    Whether to show the room name in the title.

InboxNotification.Custom

Displays a custom notification kind.

<InboxNotification  inboxNotification={inboxNotification}  kinds={{    $myCustomNotificationKind: (props) => {      const activityData = props.inboxNotification.activities[0].data;
return( <InboxNotification.Custom title={<>User <strong>{activityData.file}</strong></>} aside={<InboxNotification.Icon></InboxNotification.Icon>} {...props} > {activityData.errorDescription} </InboxNotification> ) }, }}/>
  • inboxNotificationInboxNotificationCustomDataRequired

    The inbox notification to display.

  • titleReactNodeRequired

    The inbox notification’s title.

  • childrenReactNodeRequired

    The inbox notification’s content.

  • showActionsboolean | "hover"

    How to show or hide the actions.

  • asideReactNode

    The inbox notification’s aside content. Can be combined with InboxNotification.Icon or InboxNotification.Avatar to easily follow default styles.

  • asChildbooleanDefault is false

    Replace the rendered element by the one passed as a child.

InboxNotificationList

Displays inbox notifications as a list. Each InboxNotification component will be wrapped in a li element.

<InboxNotificationList>  <InboxNotification />  <InboxNotification />  <InboxNotification /></InboxNotificationList>
InboxNotificationList
Props
  • childrenReactNode

    The inbox notifications to display.

Utilities

Components

LiveblocksUIConfig

Set configuration options for all @liveblocks/react-ui components, such as overrides.

<LiveblocksUIConfig overrides={{ locale: "fr", USER_UNKNOWN: "Anonyme" }} />
Props
  • overridesPartial<Overrides>

    Override the components’ strings.

  • componentsPartial<Components>

    Override the components’ components.

  • portalContainerHTMLElementDefault is document.body

    The container to render the portal into.

Styling and customization

Default styles

The default components come with default styles. These styles can be imported into the root of your app or directly into a CSS file with @import.

import "@liveblocks/react-ui/styles.css";

Dark mode

You can also import default dark mode styling. There are two versions to choose from, the first uses the system theme.

// Dark mode using the system theme with `prefers-color-scheme`import "@liveblocks/react-ui/styles/dark/media-query.css";

The second uses the dark class name, and two commonly used data attributes.

// Dark mode using `className="dark"`, `data-theme="dark"`, or `data-dark="true"`import "@liveblocks/react-ui/styles/dark/attributes.css";

CSS variables

The default components are built around a set of customizable CSS variables. Set these variables within .lb-root to globally style your components.

/* Styles all default Comments components */.lb-root {  --lb-accent: purple;  --lb-spacing: 1em;  --lb-radius: 0;}
  • --lb-radiusDefault is 0.5em

    The border radius scale. em values recommended.

  • --lb-spacingDefault is 1em

    The spacing scale. em values recommended.

  • --lb-accentDefault is #1177ff

    The accent color.

  • --lb-accent-foregroundDefault is #ffffff

    The foreground color used over the accent color.

  • --lb-destructiveDefault is #ff4455

    The destructive color.

  • --lb-destructive-foregroundDefault is #ffffff

    The foreground color used over the destructive color.

  • --lb-backgroundDefault is #ffffff

    The main background color.

  • --lb-foregroundDefault is #111111

    The main foreground color.

  • --lb-icon-sizeDefault is 20px

    The size of icons.

  • --lb-icon-weightDefault is 1.5px

    The stroke weight of icons.

  • --lb-avatar-radiusDefault is 50%

    The border radius used for avatars.

  • --lb-button-radiusDefault is calc(0.75 * var(--lb-radius))

    The border radius used for buttons.

  • --lb-transition-durationDefault is 0.1s

    The duration used for transitioned elements.

  • --lb-transition-easingDefault is cubic-bezier(0.4, 0, 0.2, 1)

    The easing function used for transitioned elements.

  • --lb-elevation-shadowDefault is 0 0 0 1px rgb(0 0 0 / 4%), 0 2px 6px rgb(0 0 0 / 8%), 0 8px 26px rgb(0 0 0 / 12%)

    The box shadow added to elevated elements.

  • --lb-tooltip-shadowDefault is 0 2px 4px rgb(0 0 0 / 8%), 0 4px 12px rgb(0 0 0 / 12%)

    The box shadow added to tooltips.

  • --lb-accent-contrastDefault is 8%

    Affects the lightness of accent colors. % value required.

  • --lb-destructive-contrastDefault is 8%

    Affects the lightness of destructive colors. % value required.

  • --lb-foreground-contrastDefault is 6%

    Affects the lightness of foreground colors. % value required.

Class names

Each default component has a set of predefined class names, which can be helpful for custom styling, for example.

.lb-thread {  /* Customise thread */}
.lb-composer { /* Customise composer */}

Additionally, some elements also have data attributes to provide contextual information, for example:

.lb-button[data-variant="primary"] {  /* Customise primary buttons */}
.lb-avatar[data-loading] { /* Customise avatar loading state */}

Portaled elements

Floating elements within the default components (e.g. tooltips, drowdowns, etc) are portaled to the end of the document to avoid z-index conflicts and overflow issues.

When portaled, those elements are also wrapped in a container to handle their positioning. These containers don’t have any specific class names or data attributes so they shouldn’t be targeted or styled directly, but they will mirror whichever z-index value is set on their inner element (which would be auto by default). So if you need to set a specific z-index value on floating elements, you should set it on the floating elements themselves directly, ignoring their containers. You can either target specific floating elements (e.g. .lb-tooltip, .lb-dropdown, etc) or all of them at once via the .lb-portal class name.

/* Target all floating elements */.lb-portal {  z-index: 5;}
/* Target a specific floating element */.lb-tooltip { z-index: 10;}

Overrides

Overrides can be used to customize components’ strings and localization-related properties, such as locale and reading direction.

They can be set globally for all components using LiveblocksUIConfig:

import { LiveblocksUIConfig } from "@liveblocks/react-ui";
export function App() { return ( <LiveblocksUIConfig overrides={{ locale: "fr", USER_UNKNOWN: "Anonyme" /* ... */ }} > {/* ... */} </LiveblocksUIConfig> );}

Overrides can also be set per-component, and these settings will take precedence over global settings. This is particularly useful in certain contexts, for example when you’re using a <Composer /> component for creating replies to threads:

<Composer  overrides={{    COMPOSER_PLACEHOLDER: "Reply to thread…",    COMPOSER_SEND: "Reply",  }}/>