diff --git a/CHANGELOG_PUBLIC.md b/CHANGELOG_PUBLIC.md
index c851e0c009..0b37d3d187 100644
--- a/CHANGELOG_PUBLIC.md
+++ b/CHANGELOG_PUBLIC.md
@@ -18,6 +18,47 @@ list and feel free to give them credit at the end of a line, e.g.:
-->
+# Week 9 (2026-02-27)
+
+## v3.14.1
+
+### `@liveblocks/react`
+
+- Fix paginated hooks (`useThreads`, `useInboxNotifications`, and `useAiChats`)
+ stopping pagination after the first `fetchMore()` call when auto-paginating in
+ a `useEffect`.
+
+## Zen Router
+
+- Zen Router was released, our open-source HTTP router.
+- [Documentation website for Zen Router](https://zenrouter.liveblocks.io) was published.
+- [Repo for Zen Router](https://github.com/liveblocks/zenrouter) was published.
+
+## Website
+
+- New blog post: [Introducing Zen Router: our open-source type-safe router compatible with Cloudflare Workers](https://liveblocks.io/blog/introducing-zen-router-our-open-source-type-safe-router-compatible-with-cloudflare-workers).
+
+## Examples
+
+- [Next.js Starter Kit](https://liveblocks.io/nextjs/starter-kit) was updated to support [new features](https://github.com/liveblocks/liveblocks/pull/3109).
+ - Organization switcher powered by tenants/organizations, with separate inboxes in each.
+ - New universal header built with `useIsInsideRoom`.
+ - New share menu with private/org/public permissions.
+ - Filters for private/org/public documents on dashboard.
+ - New Document shape with new permissions added.
+ - Better UX in various places and tidied project structure.
+- Fix text size in Next.js Starter Kit on mobile devices. Thank you [@chrrrs](https://github.com/chrrrs)!
+
+## Showcase
+
+- New item: [Next.js Starter Kit for realtime collaboration](https://liveblocks.io/showcase/nextjs-starter-kit-for-realtime-collaboration).
+- New item: [An inbox for each workspace](https://liveblocks.io/showcase/an-inbox-for-each-workspace).
+- New item: [Share menu with live permissions](https://liveblocks.io/showcase/share-menu-with-live-permissions).
+
+## Contributors
+
+flowflorent, chrrrs, nvie, ctnicholas
+
# Week 8 (2026-02-20)
## Open source
diff --git a/assets/agentic/agentic-workflows.png b/assets/agentic/agentic-workflows.png
new file mode 100644
index 0000000000..c50667ac8b
Binary files /dev/null and b/assets/agentic/agentic-workflows.png differ
diff --git a/assets/agentic/avatar-stack-with-ai.png b/assets/agentic/avatar-stack-with-ai.png
new file mode 100644
index 0000000000..7329836595
Binary files /dev/null and b/assets/agentic/avatar-stack-with-ai.png differ
diff --git a/assets/agentic/input-presence-ai.png b/assets/agentic/input-presence-ai.png
new file mode 100644
index 0000000000..a856ddb5b0
Binary files /dev/null and b/assets/agentic/input-presence-ai.png differ
diff --git a/assets/agentic/mention-ai.png b/assets/agentic/mention-ai.png
new file mode 100644
index 0000000000..1136a7a5cd
Binary files /dev/null and b/assets/agentic/mention-ai.png differ
diff --git a/guides/guides.json b/guides/guides.json
index af31b2f233..406332e2e4 100644
--- a/guides/guides.json
+++ b/guides/guides.json
@@ -498,7 +498,7 @@
"date": "2026-02-20"
},
{
- "title": "Enabling Agentic Workflows with Liveblocks",
+ "title": "Enabling agentic workflows with Liveblocks",
"path": "/enabling-agentic-workflows-with-liveblocks",
"topics": ["rest-api", "ai-copilots", "webhooks"],
"technologies": ["react", "nodejs"],
diff --git a/guides/pages/enabling-agentic-workflows-with-liveblocks.mdx b/guides/pages/enabling-agentic-workflows-with-liveblocks.mdx
index faea4c3a6a..b38bcd8978 100644
--- a/guides/pages/enabling-agentic-workflows-with-liveblocks.mdx
+++ b/guides/pages/enabling-agentic-workflows-with-liveblocks.mdx
@@ -1,12 +1,21 @@
---
meta:
- title: "Enabling Agentic Workflows with Liveblocks"
+ title: "Enabling agentic workflows with Liveblocks"
parentTitle: "Guides"
description:
"Use Liveblocks REST APIs to let AI agents show presence, modify storage,
and participate as collaborators in your rooms."
---
+
+
+
+
AI agents can participate as first-class collaborators inside Liveblocks rooms.
Two REST API capabilities make this possible:
@@ -30,13 +39,13 @@ The
[`POST /v2/rooms/{roomId}/presence`](/docs/api-reference/rest-api-endpoints#post-rooms-roomId-presence)
endpoint lets your agent set presence in a room just like a connected user
would. The presence expires automatically once the TTL elapses, so the agent
-never lingers after it's done.
+never lingers after it’s done.
```shell title="Endpoint"
POST https://api.liveblocks.io/v2/rooms/{roomId}/presence
```
-Authenticate with your project's **secret key** in the `Authorization` header.
+Authenticate with your project’s **secret key** in the `Authorization` header.
```shell
"Authorization: Bearer {{SECRET_KEY}}"
@@ -44,7 +53,7 @@ Authenticate with your project's **secret key** in the `Authorization` header.
The request body accepts:
-- `userId`: The agent's stable identifier.
+- `userId`: The agent’s stable identifier.
- `data`: Any presence object you want connected clients to see.
- `userInfo`: Optional name, avatar URL, and color for the agent.
- `ttl`: How long (in seconds) the presence should live (minimum: 2, maximum:
@@ -68,9 +77,18 @@ curl -X POST "https://api.liveblocks.io/v2/rooms/my-room/presence" \
A `204` response means the presence was set successfully.
+
+
+
+
### Rendering the agent as an avatar [#agent-avatar]
-Because the agent's presence is set server-side, it flows to all connected
+Because the agent’s presence is set server-side, it flows to all connected
clients through the normal Liveblocks presence system. The agent appears in
[`useOthers`](/docs/api-reference/liveblocks-react#useOthers) alongside real
users, so existing avatar stack components work without any changes.
@@ -96,6 +114,15 @@ function AvatarStack() {
The `userInfo.avatar` you pass to the presence endpoint populates `info.avatar`
here, so the agent shows up with its own avatar.
+
+
+
+
### Highlighting form fields [#highlight-fields]
Presence `data` can carry any shape you choose. A `focusedField` property, for
@@ -128,11 +155,11 @@ As the agent moves between fields, call the presence endpoint again with an
updated `focusedField` value. Each call resets the TTL, so the presence stays
alive as long as the agent keeps working.
-## Modifying storage with JSON Patch [#json-patch]
+## Modifying Storage with JSON Patch [#json-patch]
The
[`PATCH /v2/rooms/{roomId}/storage/json-patch`](/docs/api-reference/rest-api-endpoints#patch-rooms-roomId-storage-json-patch)
-endpoint lets an agent write directly to a room's Storage document over HTTP.
+endpoint lets an agent write directly to a room’s Storage document over HTTP.
The body is a JSON array of operations following the
[RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902) specification.
@@ -182,7 +209,7 @@ patch failed; the response body includes an `error` code, a human-readable
## End-to-end example: agent reviews a form [#end-to-end]
The following example walks through an agent that reviews a multi-field form. It
-uses ephemeral presence to show users what it's doing in real time, and JSON
+uses ephemeral presence to show users what it’s doing in real time, and JSON
Patch to commit its changes to Storage.
```python
@@ -249,6 +276,15 @@ in real time, no extra wiring required.
There are several natural places to start an agent workflow. Choose the one that
fits your product best, or combine multiple triggers.
+
+
+
+
### Comments webhooks—mentioning an AI agent [#comments-webhook]
Users can invoke an agent by mentioning it in a comment (e.g.
@@ -261,7 +297,7 @@ agent.
Register the agent as a mentionable user
- Add the agent's ID to [`resolveUsers`](/docs/api-reference/liveblocks-react#LiveblocksProviderResolveUsers)
+ Add the agent’s ID to [`resolveUsers`](/docs/api-reference/liveblocks-react#LiveblocksProviderResolveUsers)
and [`resolveMentionSuggestions`](/docs/api-reference/liveblocks-react#LiveblocksProviderResolveMentionSuggestions)
in your [`LiveblocksProvider`](/docs/api-reference/liveblocks-react#LiveblocksProvider)
so it appears in the `@` mention picker alongside real users.
@@ -303,7 +339,7 @@ agent.
When a comment is created, the webhook payload contains `roomId`, `threadId`,
and `commentId`. Fetch the full comment using the Liveblocks Node SDK, then use
[`getMentionsFromCommentBody`](/docs/api-reference/liveblocks-node#getMentionsFromCommentBody)
- to extract all mentions and check whether the agent's ID is among them.
+ to extract all mentions and check whether the agent’s ID is among them.
```ts file="app/api/liveblocks-webhook/route.ts"
import { Liveblocks, getMentionsFromCommentBody } from "@liveblocks/node";
diff --git a/starter-kits/nextjs-starter-kit/app/page.module.css b/starter-kits/nextjs-starter-kit/app/page.module.css
index 0a60425e09..ea0af9e4fb 100644
--- a/starter-kits/nextjs-starter-kit/app/page.module.css
+++ b/starter-kits/nextjs-starter-kit/app/page.module.css
@@ -12,11 +12,17 @@
.heroTitle {
max-width: 400px;
margin-bottom: var(--space-9);
- font-size: var(--size-4xl);
+ font-size: var(--size-3xl);
font-weight: 800;
line-height: 1.25;
}
+@media (min-width: 480px) {
+ .heroTitle {
+ font-size: var(--size-4xl);
+ }
+}
+
.heroLead {
max-width: 460px;
color: var(--color-text-lighter);