This January, we’ve made improvements to Comments, AI Copilots, onboarding.

- [Comment metadata](#comment-metadata): Enables two-way sync, custom comment
  types, more.
- [Always use knowledge](#always-use-knowledge): Require copilots to read their
  knowledge every time.
- [New quickstart flow](#new-quickstart-flow): New focused get started pages,
  plus new guides.

## Upgrade now

To use the latest features, update your packages with the following command.

```bash
npx create-liveblocks-app@latest --upgrade
```

If you were previously on Liveblocks 3.10 or below, make sure to follow our
[upgrade guides](/docs/platform/upgrading) before updating.

## Comment metadata

It’s now possible to add custom metadata to individual comments, enabling a host
of use cases such as two-way synchronization with external applications like
Slack, custom comment types, and more.

Previously, Liveblocks allowed you to add custom metadata to each individual
_thread_, essential for enabling custom thread-level functionality, such as
assigning users, adding tags, attaching X/Y coordinates, and more. With the
latest release, each _comment_ can now contain custom metadata, allowing for
additional comment-level functionality.

Let’s take a look at how this can be used.

### Two-way synchronization

Comment metadata now allows for two-way synchronization with external
applications such as Slack, meaning that when a user replies to a comment in
your application, the reply will be automatically synced to Slack, and vice
versa.

<Figure>
  <Image
    src="/images/blog/updates/january-2026/two-way-sync-liveblocks-slack.jpg"
    alt="Two-way synchronization between Liveblocks and Slack"
    width={672}
    height={385}
    quality={90}
  />
</Figure>

Slack stores IDs for each message, and using comment metadata, you can now store
these IDs in individual comments.

```json title="Slack message posted event"
{
  "type": "message",
  // +++
  "channel": "C1234567890",
  "ts": "1706892457.654321",
  "thread_ts": "1706892456.123456",
  // +++
  "user": "U2345678901",
  "text": "Hello world"
}
```

```tsx title="Duplicating the message into a Liveblocks comment"
await liveblocks.createComment({
  data: {
    body: {
      version: 1,
      content: [{ type: "paragraph", children: [{ text: "Hello world" }] }],
    },
    metadata: {
      // +++
      channel: "C1234567890",
      ts: "1706892457.654321",
      thread_ts: "1706892456.123456",
      // +++
    },
  },
  // ...
});
```

### Custom comment types

Additionally, you can now create custom comment types and render them however
you wish. For example, you could create a custom poll comment, and render this
component inside your thread.

<Figure>
  <Image
    src="/images/blog/updates/january-2026/liveblocks-poll-comment-thread.jpg"
    alt="A custom poll comment inside a thread"
    width={672}
    height={385}
    quality={90}
  />
</Figure>

To create this, you could store poll data directly inside comment metadata.

```tsx title="Creating a custom poll comment"
const poll = createComment({
  threadId: "th_d75sF3...",
  body: {
    version: 1,
    content: [
      {
        type: "paragraph",
        children: [{ text: "What is your favorite color?" }],
      },
    ],
  },
  attachments: [],
  metadata: {
    // +++
    type: "poll",
    // +++
    option_red: 3,
    option_blue: 2,
    option_green: 1,
  },
});
```

You can then create your own thread component, choose to render this any way you
like, for example with a custom `Poll` component, alongside
[`Comment`](/docs/api-reference/liveblocks-react-ui#Comment) and
[`Composer`](/docs/api-reference/liveblocks-react-ui#Composer).

```tsx title="A custom thread component with a poll"
function CustomThread({ thread }: { thread: ThreadData }) {
  return (
    <>
      {thread.comments.map((comment) => (
        <div key={comment.id}>
          <Comment comment={comment} />
          // +++
          {comment.metadata?.type === "poll" && <Poll comment={comment} />}
          // +++
        </div>
      ))}
      <Composer threadId={thread.id} />
    </>
  );
}
```

Next month we’ll be releasing an improved way to customize components in your
thread directly with the
[`Thread`](/docs/api-reference/liveblocks-react-ui#Thread) component, meaning
you can keep its benefits—such as displaying unread comment messages.

## Always use knowledge

AI copilots in our dashboard can internalize _knowledge_—uploaded files and
submitted websites—which the AI can use to answer questions on your data.
Copilots now have a new setting that allows you to force AI to read your
knowledge base before answering, ensuring each reply is relevant and accurate.
To enable it, visit your dashboard and check the “Always use knowledge” option.

<Figure>
  <MuxVideo
    playbackId="P00vZI29dwtJ9lpYxFT2xD5kyzYH7jT003K693BLN01HfQ"
    alt="Always use knowledge"
  />
</Figure>

It’s also possible to enable this setting when
[modifying your copilot programmatically](/docs/ready-made-features/ai-copilots/copilots#Modifying-copilots-programmatically).

```ts
const copilot = await liveblocks.createAiCopilot({
  name: "Assistant",
  systemPrompt: "You are an AI assistant",
  // +++
  alwaysUseKnowledge: true,
  // +++
  // ...
});
```

## New quickstart flow

We’ve thought through our whole onboarding flow, and created a new interactive
quickstart section that helps you find specific guides for your use case and
technology more quickly than ever. You can also just skip right to getting your
API keys.

<Figure>
  <MuxVideo
    playbackId="01Qyn89CcnjYKtp00P00HYMlp5S8rZ3LQ2aJ01PHoeJV9TE"
    alt="New quickstart"
  />
</Figure>

Alongside the new flow, we’ve added a number of new guides on
[setting up Liveblocks Notifications](/docs/get-started/notifications), and a
new guide for
[creating a collaborative Tldraw whiteboard](/docs/get-started/nextjs-tldraw).
This update lays the groundwork for more get started guides, which will be
coming soon!

## Minor improvements

- Support typing comment metadata globally via the `Liveblocks` interface.
- Add new parameters to `createThread`, `createComment`, and `editComment` to
  attach and update comment metadata.
- Add `editCommentMetadata` method to update only a commentʼs metadata.
- Add new parameters to `useCreateThread`, `useCreateComment`, and
  `useEditComment` to attach and update comment metadata.
- Add `useEditCommentMetadata` hook to update only a commentʼs metadata.
- Add `commentMetadata` prop to `Composer` to attach and update comment
  metadata.
- Add `commentMetadata` prop to `FloatingComposer` to attach and update comment
  metadata.
- Add new parameters to `createThread`, `createComment`, and `editComment` to
  attach and update comment metadata.
- Add `editCommentMetadata` method to update only a commentʼs metadata.
- Add `commentMetadataUpdated` webhook event.
- Add more detailed timing info to `enableDebugLogging` to better debug
  connection issues.
- Data refreshes much more quickly when viewing rooms in the dashboard.
- Added floating avatar on pricing page.
- Bump hardcoded client-side socket connection timeout from 10s to 20s.
- Internal refactorings to prepare for upcoming protocol updates.
- Improve `CommentBody` types.
- Fix an issue where `Composer` and `AiComposer` would throw an error when
  mounted/unmounted.
- Fix issue where storage subscriptions wouldn't fire after concurrent move and
  set operations, causing stale `LiveList` state in UI.
- Fix an issue where `Composer` and `AiComposer` would throw an error when
  mounted/unmounted.
- Fix `Toolbar` in `@liveblocks/react-tiptap` not reflecting the editorʼs
  current state.
- Fix bug with linking integrations to `create-liveblocks-app` CLI.

### Upgrade

To use these latest features, update your packages with:

```bash
npx create-liveblocks-app@latest --upgrade
```

## Contributors

<Contributors
  gitHubUsernames={[
    "ctnicholas",
    "nimeshnayaju",
    "nvie",
    "marcbouchenoire",
    "pierrelevaillant",
    "stevenfabre",
  ]}
/>