From e8b24b371ff46d86338e35706a3e905d49fb1e56 Mon Sep 17 00:00:00 2001 From: Marc Bouchenoire Date: Mon, 11 May 2026 10:18:55 +0200 Subject: [PATCH 1/2] Fix public changelog (#3405) --- CHANGELOG_PUBLIC.md | 327 +++++++++++++++++++++++++++++--------------- 1 file changed, 220 insertions(+), 107 deletions(-) diff --git a/CHANGELOG_PUBLIC.md b/CHANGELOG_PUBLIC.md index 6d40c6f5cac..ff0e6d0c013 100644 --- a/CHANGELOG_PUBLIC.md +++ b/CHANGELOG_PUBLIC.md @@ -18,35 +18,79 @@ list and feel free to give them credit at the end of a line, e.g.: --> -# Week 18 (2026-05-01) +# Week 19 (2026-05-08) + +## v3.19.0 + +### `@liveblocks/node` + +- Add new `markdownToCommentBody` helper to convert Markdown strings into + `CommentBody` objects. + +### `@liveblocks/client` + +- `room.history.disable(fn)` is now officially supported and no longer + experimental. It allows running storage mutations without them appearing on + the undo/redo stacks and it’s intended for background/async writes (e.g. + writing back AI generation results) that should not be undoable. + +### `@liveblocks/react-tiptap` + +- Fix keyboard shortcut in strikethrough tooltip. (Thanks @HellBoy-OP for the + contribution!) +- Fix Yjs undo/redo silently breaking after `editor.registerPlugin` / + `unregisterPlugin` is called (e.g. when Tiptap's `BubbleMenu`, `DragHandle`, + or `SlashCommand` mount). The reattach `restore()` is now installed + unconditionally on view destroy, matching upstream + `@tiptap/extension-collaboration`. (Thanks @lucasmotta for the contribution!) ## Liveblocks dev server (v1.4.1) -- Fix: `client.getOrCreateRoom()` no longer errors when the room already exists, matching production behavior. -- Fix: Yjs document updates made via `PUT /v2/rooms//ydoc` now get broadcast to connected WebSocket clients, matching production behavior. +- Fix: `client.getOrCreateRoom()` no longer errors when the room already exists, + matching production behavior. +- Fix: Yjs document updates made via `PUT /v2/rooms//ydoc` now get + broadcast to connected WebSocket clients, matching production behavior. ## Contributors -nvie +nvie, marcbouchenoire, HellBoy-OP, lucasmotta # Week 17 (2026-04-24) +## v3.18.5 + +### `@liveblocks/react-tiptap` + +- Support overlapping comment marks, they now all appear in the + `AnchoredThreads` and `FloatingThreads` components. + +## v3.18.4 + +### `@liveblocks/emails` + +- Mark `yjs` and `y-prosemirror` as required peer dependencies. + ## Website -- New blog post: [How CRDTs and sync engines keep realtime lists ordered with fractional indexing](https://liveblocks.io/blog/how-crdts-and-sync-engines-keep-realtime-lists-ordered-with-fractional-indexing). +- New blog post: + [How CRDTs and sync engines keep realtime lists ordered with fractional indexing](https://liveblocks.io/blog/how-crdts-and-sync-engines-keep-realtime-lists-ordered-with-fractional-indexing). ## Infrastructure -- We're almost done migrating over all rooms to our new v2 realtime data storage engine–we're deep in the long tail! (For the benefits of this, [read more here](https://liveblocks.io/docs/guides/about-the-new-storage-engine).) +- We're almost done migrating over all rooms to our new v2 realtime data storage + engine–we're deep in the long tail! (For the benefits of this, + [read more here](https://liveblocks.io/docs/guides/about-the-new-storage-engine).) ## Documentation -- New get started guide: [Multiplayer Handsontable](https://liveblocks.io/docs/get-started/nextjs-multiplayer-handsontable). -- New get started guide: [Commenting in Handsontable](https://liveblocks.io/docs/get-started/nextjs-comments-handsontable). +- New get started guide: + [Multiplayer Handsontable](https://liveblocks.io/docs/get-started/nextjs-multiplayer-handsontable). +- New get started guide: + [Commenting in Handsontable](https://liveblocks.io/docs/get-started/nextjs-comments-handsontable). ## Contributors -ctnicholas, nvie, ofoucherot +ctnicholas, nvie, ofoucherot, marcbouchenoire # Week 16 (2026-04-17) @@ -54,37 +98,50 @@ ctnicholas, nvie, ofoucherot ### `@liveblocks/*` -- Third-party libraries like `yjs`, `@tiptap/*`, and `@blocknote/*` are now declared as peer dependencies instead of bundled dependencies across all packages that use them. +- Third-party libraries like `yjs`, `@tiptap/*`, and `@blocknote/*` are now + declared as peer dependencies instead of bundled dependencies across all + packages that use them. ## v3.18.2 ### `@liveblocks/client` -- New experimental `room.history.disable(fn)` API that allows running storage mutations without them appearing on the undo/redo stacks. Intended for background/async writes (e.g. writing back AI generation results) that should not be undoable. -- Fix `ToJson` type losing specific value types for `Record` fields in Storage +- New experimental `room.history.disable(fn)` API that allows running storage + mutations without them appearing on the undo/redo stacks. Intended for + background/async writes (e.g. writing back AI generation results) that should + not be undoable. +- Fix `ToJson` type losing specific value types for `Record` fields + in Storage ## v3.18.1 ### `@liveblocks/react-ui` - Mentions suggestions now appear in more cases after typing `@`: - - After punctuation like `!`, `.`, `(`, etc. (e.g. `Hello!@`, `cc: the other team (@`) + - After punctuation like `!`, `.`, `(`, etc. (e.g. `Hello!@`, + `cc: the other team (@`) - After emojis (e.g. `Hello 👋@`) ## Infrastructure - Moved the public monorepo from NPM to pnpm. -- Started the transparent internal migration of old rooms still on the v1 realtime data storage engine to the new v2 engine, [learn more about the benefits](https://liveblocks.io/docs/guides/about-the-new-storage-engine). +- Started the transparent internal migration of old rooms still on the v1 + realtime data storage engine to the new v2 engine, + [learn more about the benefits](https://liveblocks.io/docs/guides/about-the-new-storage-engine). ## Examples -- New example: [Handsontable comments](https://liveblocks.io/examples/handsontable-comments/nextjs-comments-handsontable). -- New example: [Multiplayer Handsontable](https://liveblocks.io/examples/multiplayer-handsontable/nextjs-multiplayer-handsontable). +- New example: + [Handsontable comments](https://liveblocks.io/examples/handsontable-comments/nextjs-comments-handsontable). +- New example: + [Multiplayer Handsontable](https://liveblocks.io/examples/multiplayer-handsontable/nextjs-multiplayer-handsontable). ## Website -- New blog post: [Unveil Week recap: Realtime collaboration for humans and agents](https://liveblocks.io/blog/unveil-week-recap-realtime-collaboration-for-humans-and-agents). -- New blog post: [Official n8n nodes for Liveblocks](https://liveblocks.io/blog/official-n8n-nodes-for-liveblocks). +- New blog post: + [Unveil Week recap: Realtime collaboration for humans and agents](https://liveblocks.io/blog/unveil-week-recap-realtime-collaboration-for-humans-and-agents). +- New blog post: + [Official n8n nodes for Liveblocks](https://liveblocks.io/blog/official-n8n-nodes-for-liveblocks). ## Contributors @@ -133,16 +190,24 @@ For full upgrade instructions, see the ## Website -- New blog post: [AI agents are becoming native users of software](https://liveblocks.io/blog/ai-agents-are-becoming-native-users-of-software). -- New blog post: [Introducing Feeds and APIs for Agent Workflows](https://liveblocks.io/blog/introducing-feeds-and-apis-for-agent-workflows). -- New blog post: [Multiplayer SDK for React Flow: Realtime collaboration between humans and agents](https://liveblocks.io/blog/multiplayer-sdk-for-react-flow-realtime-collaboration-between-humans-and-agents). -- New blog post: [Chat SDK adapter for Liveblocks](https://liveblocks.io/blog/chat-sdk-adapter-for-liveblocks). -- New blog post: [Python SDK for Liveblocks](https://liveblocks.io/blog/python-sdk-for-liveblocks). -- New blog post: [Agent skills for Liveblocks](https://liveblocks.io/blog/agent-skills-for-liveblocks). +- New blog post: + [AI agents are becoming native users of software](https://liveblocks.io/blog/ai-agents-are-becoming-native-users-of-software). +- New blog post: + [Introducing Feeds and APIs for Agent Workflows](https://liveblocks.io/blog/introducing-feeds-and-apis-for-agent-workflows). +- New blog post: + [Multiplayer SDK for React Flow: Realtime collaboration between humans and agents](https://liveblocks.io/blog/multiplayer-sdk-for-react-flow-realtime-collaboration-between-humans-and-agents). +- New blog post: + [Chat SDK adapter for Liveblocks](https://liveblocks.io/blog/chat-sdk-adapter-for-liveblocks). +- New blog post: + [Python SDK for Liveblocks](https://liveblocks.io/blog/python-sdk-for-liveblocks). +- New blog post: + [Agent skills for Liveblocks](https://liveblocks.io/blog/agent-skills-for-liveblocks). ## Documentation -- Mention missing [`updatedAt`](https://liveblocks.io/docs/api-reference/liveblocks-node#patch-rooms-roomId-feeds-feedId-messages-messageId) field in `updateFeedMessage` reference. +- Mention missing + [`updatedAt`](https://liveblocks.io/docs/api-reference/liveblocks-node#patch-rooms-roomId-feeds-feedId-messages-messageId) + field in `updateFeedMessage` reference. ## Contributors @@ -219,22 +284,29 @@ nvie, ctnicholas, stevenfabre, marcbouchenoire ## Website -- [Liveblocks Unveil](https://liveblocks.io/unveil/april-2026): April 6–10, 5 days of launches. +- [Liveblocks Unveil](https://liveblocks.io/unveil/april-2026): April 6–10, 5 + days of launches. ## Documentation - New page: [n8n nodes](https://liveblocks.io/docs/tools/n8n-nodes). -- New page: [AI Collaboration](https://liveblocks.io/docs/collaboration-features/ai-collaboration). -- New get started: [Next.js + Realtime feeds](https://liveblocks.io/docs/get-started/nextjs-feeds). -- New get started: [Next.js + React Flow](https://liveblocks.io/docs/get-started/nextjs-react-flow). +- New page: + [AI Collaboration](https://liveblocks.io/docs/collaboration-features/ai-collaboration). +- New get started: + [Next.js + Realtime feeds](https://liveblocks.io/docs/get-started/nextjs-feeds). +- New get started: + [Next.js + React Flow](https://liveblocks.io/docs/get-started/nextjs-react-flow). - Add Feeds to API reference pages. - New concepts and WebSocket images. ## Examples -- New example: [AI Comments](https://liveblocks.io/examples/ai-comments/nextjs-comments-ai). -- New example: [Chat SDK Bot](https://liveblocks.io/examples/chat-sdk-bot/nextjs-chat-sdk-bot). -- New example: [Chat SDK AI Bot](https://liveblocks.io/examples/chat-sdk-ai-bot/nextjs-chat-sdk-ai-bot). +- New example: + [AI Comments](https://liveblocks.io/examples/ai-comments/nextjs-comments-ai). +- New example: + [Chat SDK Bot](https://liveblocks.io/examples/chat-sdk-bot/nextjs-chat-sdk-bot). +- New example: + [Chat SDK AI Bot](https://liveblocks.io/examples/chat-sdk-ai-bot/nextjs-chat-sdk-ai-bot). ## Contributors @@ -267,7 +339,8 @@ New dev server features: ## Showcase -- New item: [Realtime design like Figma](https://liveblocks.io/showcase/realtime-design-like-figma). +- New item: + [Realtime design like Figma](https://liveblocks.io/showcase/realtime-design-like-figma). ## Contributors @@ -310,26 +383,33 @@ New dev server features: - Room filtering support - Room Node.js methods and REST APIs are now fully supported -See [dev server documentation](https://liveblocks.io/docs/tools/dev-server) for the updated feature matrix. +See [dev server documentation](https://liveblocks.io/docs/tools/dev-server) for +the updated feature matrix. ## Dashboard -- We added support for setting description on projects for better documentation and organization +- We added support for setting description on projects for better documentation + and organization - Fixed a bug preventing inviting new members correctly -- Internal refactoring of dashboard components to improve performance and efficiency +- Internal refactoring of dashboard components to improve performance and + efficiency ## Infrastructure -- Mangement API: We added support for setting description on projects for better documentation and organization. +- Mangement API: We added support for setting description on projects for better + documentation and organization. ## Documentation -- New API reference: [Python SDK](https://liveblocks.io/docs/api-reference/liveblocks-python). +- New API reference: + [Python SDK](https://liveblocks.io/docs/api-reference/liveblocks-python). ## Website -- New blog post: [What's new in Liveblocks: February 2026](https://liveblocks.io/blog/whats-new-in-liveblocks-february-2026). -- New blog post: [New React components for adding realtime presence and contextual commenting to your app](https://liveblocks.io/blog/new-react-components-for-adding-realtime-presence-and-contextual-commenting-to-your-app). +- New blog post: + [What's new in Liveblocks: February 2026](https://liveblocks.io/blog/whats-new-in-liveblocks-february-2026). +- New blog post: + [New React components for adding realtime presence and contextual commenting to your app](https://liveblocks.io/blog/new-react-components-for-adding-realtime-presence-and-contextual-commenting-to-your-app). ## Contributors @@ -375,7 +455,8 @@ nvie, sugardarius, nimeshnayaju, pierrelevaillant, marcbouchenoire, ctnicholas ## Examples -- Improve canvas comments example to prevent a conflict after moving a comment pin twice in rapid succession. +- Improve canvas comments example to prevent a conflict after moving a comment + pin twice in rapid succession. ## Contributors @@ -414,17 +495,24 @@ nvie, marcbouchenoire, ctnicholas ## Examples -- New example: [AG Grid Comments](https://liveblocks.io/examples/ag-grid-comments/nextjs-comments-ag-grid). +- New example: + [AG Grid Comments](https://liveblocks.io/examples/ag-grid-comments/nextjs-comments-ag-grid). - Update old examples to use new presence and commenting components. ## Documentation -- New quickstart: [Draggable comments with Next.js](https://liveblocks.io/docs/get-started/nextjs-comments-canvas). -- New quickstart: [Commenting inside AG Grid with Next.js](https://liveblocks.io/docs/get-started/nextjs-comments-ag-grid). -- New quickstart: [Commenting inside a table with Next.js](https://liveblocks.io/docs/get-started/nextjs-comments-table). -- New quickstart: [Realtime avatar and cursor presence with Next.js](https://liveblocks.io/docs/get-started/nextjs-presence). -- New guide: [How to add users to Liveblocks presence components](https://liveblocks.io/docs/guides/how-to-add-users-to-liveblocks-presence-components). -- Mention `sk_localdev` and `pk_localdev` keys more explicitly in dev server docs. +- New quickstart: + [Draggable comments with Next.js](https://liveblocks.io/docs/get-started/nextjs-comments-canvas). +- New quickstart: + [Commenting inside AG Grid with Next.js](https://liveblocks.io/docs/get-started/nextjs-comments-ag-grid). +- New quickstart: + [Commenting inside a table with Next.js](https://liveblocks.io/docs/get-started/nextjs-comments-table). +- New quickstart: + [Realtime avatar and cursor presence with Next.js](https://liveblocks.io/docs/get-started/nextjs-presence). +- New guide: + [How to add users to Liveblocks presence components](https://liveblocks.io/docs/guides/how-to-add-users-to-liveblocks-presence-components). +- Mention `sk_localdev` and `pk_localdev` keys more explicitly in dev server + docs. - Mention `["comments:write"]` permission under authentication. ## Contributors @@ -444,29 +532,37 @@ nperez0111, marcbouchenoire, ctnicholas ## Zen Router - Zen Router was released, our open-source HTTP router. -- [Documentation website for Zen Router](https://zenrouter.liveblocks.io) was published. +- [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). +- 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. +- [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)! +- 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). +- 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 @@ -476,13 +572,19 @@ flowflorent, chrrrs, nvie, ctnicholas ## Open source -This week we've [open-sourced the Liveblocks sync engine and dev server](https://liveblocks.io/blog/open-sourcing-the-liveblocks-sync-engine-and-dev-server). +This week we've +[open-sourced the Liveblocks sync engine and dev server](https://liveblocks.io/blog/open-sourcing-the-liveblocks-sync-engine-and-dev-server). ## v3.14 🥧 -This release adds support for opting-in to the new storage engine on a per-room basis. The new storage engine can support larger documents, is more performant, is considered more stable, and will eventually become our default engine for all new rooms in the future. As of this release, the default storage engine still remains engine version 1. +This release adds support for opting-in to the new storage engine on a per-room +basis. The new storage engine can support larger documents, is more performant, +is considered more stable, and will eventually become our default engine for all +new rooms in the future. As of this release, the default storage engine still +remains engine version 1. -To give it a try, simply pass `engine: 2` when entering a _new_ room. After a room is created, you cannot change the engine it was created with anymore. +To give it a try, simply pass `engine: 2` when entering a _new_ room. After a +room is created, you cannot change the engine it was created with anymore. ```ts // Vanilla JS @@ -500,57 +602,85 @@ or: ### `@liveblocks/client` -- Support for selecting the preferred engine when entering new rooms: `client.enterRoom("my-new-room", { engine: 2 })` +- Support for selecting the preferred engine when entering new rooms: + `client.enterRoom("my-new-room", { engine: 2 })` - Internal protocol optimizations to support larger storage documents -- Add new config option `createClient({ baseUrl: "https://..." })` to allow connecting to the [Liveblocks dev server](https://liveblocks.io/docs/tools/dev-server) +- Add new config option `createClient({ baseUrl: "https://..." })` to allow + connecting to the + [Liveblocks dev server](https://liveblocks.io/docs/tools/dev-server) - Improve `LiveList` performance when processing large batches of operations -- Improve `LiveList.push()` efficiency to prevent unbounded position string growth over time +- Improve `LiveList.push()` efficiency to prevent unbounded position string + growth over time - Fix crash when clearing documents with a large number of keys -- Remove the `largeMessageStrategy` client option. The WebSocket message limit has been increased from 1 MB to 32 MB, making this setting obsolete. +- Remove the `largeMessageStrategy` client option. The WebSocket message limit + has been increased from 1 MB to 32 MB, making this setting obsolete. ### `@liveblocks/react` -- Support for selecting the preferred engine when entering new rooms: `...` -- Add new config option `` to allow connecting to the [Liveblocks dev server](https://liveblocks.io/docs/tools/dev-server) -- Exclude marking a thread or inbox notification as read from blocking navigation when `preventUnsavedChanges` is enabled. +- Support for selecting the preferred engine when entering new rooms: + `...` +- Add new config option `` to allow + connecting to the + [Liveblocks dev server](https://liveblocks.io/docs/tools/dev-server) +- Exclude marking a thread or inbox notification as read from blocking + navigation when `preventUnsavedChanges` is enabled. ### `@liveblocks/react-tiptap` and `@liveblocks/react-lexical` -- Portaled elements now respect the `portalContainer` option from `@liveblocks/react-ui`’s `LiveblocksUiConfig` instead of always using `document.body`. +- Portaled elements now respect the `portalContainer` option from + `@liveblocks/react-ui`’s `LiveblocksUiConfig` instead of always using + `document.body`. ### `@liveblocks/zustand` and `@liveblocks/redux` -- Support for selecting the preferred engine when entering new rooms: `enterRoom("my-new-room", { engine: 2 })` +- Support for selecting the preferred engine when entering new rooms: + `enterRoom("my-new-room", { engine: 2 })` ### `@liveblocks/node` -- Add new `.setPresence()` method to set ephemeral presence for a user in a room via the REST API, without requiring a WebSocket connection -- Deprecated `tenantId` parameter in client methods, use `organizationId` instead. +- Add new `.setPresence()` method to set ephemeral presence for a user in a room + via the REST API, without requiring a WebSocket connection +- Deprecated `tenantId` parameter in client methods, use `organizationId` + instead. ## Website -- New blog post: [Open sourcing the Liveblocks sync engine and dev server](https://liveblocks.io/blog/open-sourcing-the-liveblocks-sync-engine-and-dev-server). +- New blog post: + [Open sourcing the Liveblocks sync engine and dev server](https://liveblocks.io/blog/open-sourcing-the-liveblocks-sync-engine-and-dev-server). ## Documentation - New page: [Dev server](https://liveblocks.io/docs/tools/dev-server). -- New page: [Management API](https://liveblocks.io/docs/platform/management-api). -- New page: [Multi-Factor Authentication](https://liveblocks.io/docs/platform/account-management/mfa). -- New guide: [How to set up Continuous Integration (CI) testing](https://liveblocks.io/docs/guides/how-to-set-up-continuous-integration-ci-testing). -- New guide: [How to set up End-to-End (E2E) testing with Playwright](https://liveblocks.io/docs/guides/how-to-set-up-end-to-end-e2e-testing-with-playwright). -- New guide: [The new Storage engine and its benefits](https://liveblocks.io/docs/guides/about-the-new-storage-engine). -- Updated [overview information on Storage](https://liveblocks.io/docs/ready-made-features/multiplayer/sync-engine/liveblocks-storage). -- Updated [overview inforamtion on Yjs](https://liveblocks.io/docs/ready-made-features/multiplayer/sync-engine/liveblocks-yjs). +- New page: + [Management API](https://liveblocks.io/docs/platform/management-api). +- New page: + [Multi-Factor Authentication](https://liveblocks.io/docs/platform/account-management/mfa). +- New guide: + [How to set up Continuous Integration (CI) testing](https://liveblocks.io/docs/guides/how-to-set-up-continuous-integration-ci-testing). +- New guide: + [How to set up End-to-End (E2E) testing with Playwright](https://liveblocks.io/docs/guides/how-to-set-up-end-to-end-e2e-testing-with-playwright). +- New guide: + [The new Storage engine and its benefits](https://liveblocks.io/docs/guides/about-the-new-storage-engine). +- Updated + [overview information on Storage](https://liveblocks.io/docs/ready-made-features/multiplayer/sync-engine/liveblocks-storage). +- Updated + [overview inforamtion on Yjs](https://liveblocks.io/docs/ready-made-features/multiplayer/sync-engine/liveblocks-yjs). ## Dashboard -- The [Management API](https://liveblocks.io/docs/platform/management-api) is now available in private beta for Enterprise customers. -- We added [Multi-Factor Authentication (MFA)](https://liveblocks.io/docs/platform/management-api) support. Users can now enable MFA in their account pesonal settings for enhanced security. -- New toggle to opt-in to use v2 Storage engine for all new rooms created going forward. +- The [Management API](https://liveblocks.io/docs/platform/management-api) is + now available in private beta for Enterprise customers. +- We added + [Multi-Factor Authentication (MFA)](https://liveblocks.io/docs/platform/management-api) + support. Users can now enable MFA in their account pesonal settings for + enhanced security. +- New toggle to opt-in to use v2 Storage engine for all new rooms created going + forward. ## Showcase -- New item: [Develop locally with the dev server)[https://liveblocks.io/showcase/dev-server-tldraw]. +- New item: [Develop locally with the dev + server)[https://liveblocks.io/showcase/dev-server-tldraw]. ## Examples @@ -558,7 +688,8 @@ or: ## Contributors -nvie, marcbouchenoire, flowflorent, jrowny, ctnicholas, sugardarius, pierrelevaillant, nimeshnayaju +nvie, marcbouchenoire, flowflorent, jrowny, ctnicholas, sugardarius, +pierrelevaillant, nimeshnayaju # Week 7 (2026-02-13) @@ -566,17 +697,20 @@ nvie, marcbouchenoire, flowflorent, jrowny, ctnicholas, sugardarius, pierrelevai ### `@liveblocks/react-blocknote` -- Replace `y-tiptap` with `y-prosemirror` to prevent plugin key conflict, which was causing change source to be incorrectly set in BlockNote. +- Replace `y-tiptap` with `y-prosemirror` to prevent plugin key conflict, which + was causing change source to be incorrectly set in BlockNote. ## Documentation - Add `.md` to the end of any docs page to view a markdown representation of it. - This `.md` is mentioned as an `alternate` link on each docs page. -- Fetching any docs page with a priority `text/markdown` header will return markdown. +- Fetching any docs page with a priority `text/markdown` header will return + markdown. ## Showcase -- New item: [Multiplayer table](https://liveblocks.io/showcase/multiplayer-table). +- New item: + [Multiplayer table](https://liveblocks.io/showcase/multiplayer-table). ## Contributors @@ -5370,13 +5504,11 @@ In **@liveblocks/react**: https://liveblocks.io/docs/guides/troubleshooting#stale-props-zombie-child - In **@liveblocks/zustand**: - - Fix a confusing error message # v0.18.2 - In **@liveblocks/react**: - - Make sure that `useOther` will not rerender if tracked users already left the room, so that child components won't get rerendered before the parent got the chance to unmount them. @@ -5385,7 +5517,6 @@ In **@liveblocks/react**: # v0.18.1 - In **@liveblocks/react**: - - Fix a bug that could cause an error when patching presence during local development. Not an issue in production builds. (#505) @@ -5397,7 +5528,6 @@ For information, please read our ## New React hooks ✨ - In **@liveblocks/react**: - - [`useStorage`](https://liveblocks.io/docs/api-reference/liveblocks-react#useStorage) - [`useMutation`](https://liveblocks.io/docs/api-reference/liveblocks-react#useMutation) - [`useSelf`](https://liveblocks.io/docs/api-reference/liveblocks-react#useSelf) @@ -5408,7 +5538,6 @@ For information, please read our (singular) - In **@liveblocks/client**: - - New [`.toImmutable()`](https://liveblocks.io/docs/api-reference/liveblocks-client#LiveObject.toImmutable) method on `LiveObject`, `LiveList`, and `LiveMap` lets you work with an @@ -5454,19 +5583,16 @@ In **@liveblocks/react**: ## New history APIs ↩️ ↪️ - In **@liveblocks/client**: - - Add `canUndo()` and `canRedo()` utilities to `room.history` - Add `"history"` event type to `room.subscribe()` to subscribe to the current user's history changes - In **@liveblocks/react**: - - Add `useCanUndo()` and `useCanRedo()` hooks # v0.17.7 - In **@liveblocks/zustand**: - - Simplify zustand middleware integration with Typescript. `TPresence`, `TStorage`, `TUserMeta`, and `TRoomEvent` are now optional. @@ -5548,13 +5674,11 @@ useStore(state => state.liveblocks.others[0].presence?.isTyping) # v0.17.6 - In **@liveblocks/react**: - - Expose `RoomContext` in the return value of `createRoomContext()` # v0.17.5 - In **@liveblocks/react**: - - Fix bug where changing the `key` argument of `useMap()`, `useList()`, `useObject()` did not resubscribe to updates correctly - Ignore changes to the `RoomProvider`'s initial presence/storage props on @@ -5606,12 +5730,10 @@ It's surprisingly simple! ## New APIs ✨ - In **@liveblocks/react**: - - [`createRoomContext()`](https://liveblocks.io/docs/api-reference/liveblocks-react#createRoomContext) is now the preferred way to initialize hooks. - In the API: - - New endpoint to [Get Users in a Room](https://liveblocks.io/docs/api-reference/rest-api-endpoints#GetRoomUsers) - New endpoint to @@ -5625,13 +5747,11 @@ It's surprisingly simple! ## Breaking changes - In **@liveblocks/client**: - - Removed old `Room.unsubscribe()` API ## New deprecations - In **@liveblocks/client**: - - The `defaultPresence` option to `client.enter()` will get renamed to `initialPresence` - The `defaultStorageRoot` option to `client.enter()` will get renamed to @@ -5640,7 +5760,6 @@ It's surprisingly simple! or `new LiveMap([])` - In **@liveblocks/react**: - - Importing the React hooks directly is deprecated, instead use the new `createRoomContext()` helper. For help, read the [Recommended Upgrade Steps section](https://liveblocks.io/docs/platform/upgrading/0.17#recommended-upgrade-steps) @@ -5711,7 +5830,6 @@ Fix bug in example code suggested in deprecation warning. ## Bug fixes - In **@liveblocks/client**: - - If you're using `@liveblocks/client` in a ES2015 context, you no longer have to polyfill `Object.fromEntries()`. @@ -5729,15 +5847,12 @@ Fix bug in example code suggested in deprecation warning. ## Bug fixes - In **@liveblocks/client**: - - Fix bug where internal presence state could not get restored correctly after undo/redo in certain circumstances. - In **@liveblocks/zustand** and **@liveblocks/redux**: - - Fixes an issue when initializing an array with items would result in having duplicated items in other clients. Example: - - Client A updates state : `{ list: [0] }` - Client B states is updated to : `{ list: [0, 0] }` @@ -5746,7 +5861,6 @@ Fix bug in example code suggested in deprecation warning. ## Bug fixes - In **@liveblocks/client**: - - Fix small bug related to new `JsonObject` type, which would reject some values that were legal JSON objects. @@ -5755,7 +5869,6 @@ Fix bug in example code suggested in deprecation warning. ## Bug fixes - In **@liveblocks/react**: - - Fix issue with React 18 and StrictMode. # v0.16.0 From 5952d6b0fb16850e76bda7222fc50c81ee8b233f Mon Sep 17 00:00:00 2001 From: Le Vaillant Pierre Date: Mon, 11 May 2026 12:33:48 +0200 Subject: [PATCH 2/2] Add Integrations docs, prompt sidecars, and n8n path links (#3388) Co-authored-by: Cursor Agent Co-authored-by: Le Vaillant Pierre Co-authored-by: Chris Nicholas --- CHANGELOG_PUBLIC.md | 2 +- .../liveblocks-chat-sdk-adapter.mdx | 4 +- docs/pages/api-reference/liveblocks-node.mdx | 2 +- .../ai-collaboration.mdx | 2 +- docs/pages/integrations.mdx | 133 +++++++++ .../pages/integrations/_provider-template.mdx | 109 +++++++ docs/pages/integrations/bolt.mdx | 70 +++++ docs/pages/integrations/claude-code.mdx | 130 ++++++++ docs/pages/integrations/claude-desktop.mdx | 144 +++++++++ docs/pages/integrations/codex.mdx | 137 +++++++++ docs/pages/integrations/cursor.mdx | 141 +++++++++ docs/pages/integrations/lovable.mdx | 70 +++++ .../{tools => integrations}/n8n-nodes.mdx | 132 ++++++--- docs/pages/integrations/neon.mdx | 271 +++++++++++++++++ docs/pages/integrations/planetscale.mdx | 280 ++++++++++++++++++ docs/pages/integrations/replit.mdx | 69 +++++ docs/pages/integrations/supabase.mdx | 279 +++++++++++++++++ docs/pages/integrations/supabase.prompt.md | 21 ++ docs/pages/integrations/v0.mdx | 70 +++++ docs/pages/tools/agent-skills.mdx | 2 + docs/pages/tools/agent-skills.prompt.md | 18 ++ docs/pages/tools/mcp-server.mdx | 115 +++---- docs/pages/tools/mcp-server.prompt.md | 18 ++ docs/routes.json | 61 +++- ...t-data-to-a-planetscale-mysql-database.mdx | 93 +++--- ...t-data-to-a-supabase-postgres-database.mdx | 93 +++--- ...ent-data-to-a-vercel-postgres-database.mdx | 91 +++--- ...t-data-to-a-planetscale-mysql-database.mdx | 93 +++--- ...t-data-to-a-supabase-postgres-database.mdx | 93 +++--- ...ent-data-to-a-vercel-postgres-database.mdx | 91 +++--- 30 files changed, 2392 insertions(+), 442 deletions(-) create mode 100644 docs/pages/integrations.mdx create mode 100644 docs/pages/integrations/_provider-template.mdx create mode 100644 docs/pages/integrations/bolt.mdx create mode 100644 docs/pages/integrations/claude-code.mdx create mode 100644 docs/pages/integrations/claude-desktop.mdx create mode 100644 docs/pages/integrations/codex.mdx create mode 100644 docs/pages/integrations/cursor.mdx create mode 100644 docs/pages/integrations/lovable.mdx rename docs/pages/{tools => integrations}/n8n-nodes.mdx (55%) create mode 100644 docs/pages/integrations/neon.mdx create mode 100644 docs/pages/integrations/planetscale.mdx create mode 100644 docs/pages/integrations/replit.mdx create mode 100644 docs/pages/integrations/supabase.mdx create mode 100644 docs/pages/integrations/supabase.prompt.md create mode 100644 docs/pages/integrations/v0.mdx create mode 100644 docs/pages/tools/agent-skills.prompt.md create mode 100644 docs/pages/tools/mcp-server.prompt.md diff --git a/CHANGELOG_PUBLIC.md b/CHANGELOG_PUBLIC.md index ff0e6d0c013..2222d305ff9 100644 --- a/CHANGELOG_PUBLIC.md +++ b/CHANGELOG_PUBLIC.md @@ -289,7 +289,7 @@ nvie, ctnicholas, stevenfabre, marcbouchenoire ## Documentation -- New page: [n8n nodes](https://liveblocks.io/docs/tools/n8n-nodes). +- New page: [n8n nodes](https://liveblocks.io/docs/integrations/n8n-nodes). - New page: [AI Collaboration](https://liveblocks.io/docs/collaboration-features/ai-collaboration). - New get started: diff --git a/docs/pages/api-reference/liveblocks-chat-sdk-adapter.mdx b/docs/pages/api-reference/liveblocks-chat-sdk-adapter.mdx index 8217e09aee5..377063e16a6 100644 --- a/docs/pages/api-reference/liveblocks-chat-sdk-adapter.mdx +++ b/docs/pages/api-reference/liveblocks-chat-sdk-adapter.mdx @@ -25,7 +25,7 @@ Before using this adapter, ensure you have: 1. A [Liveblocks project](/docs/get-started) with rooms using [Comments](/docs/products/comments). 2. A **secret key** (`sk_...`) from the Liveblocks dashboard for REST API calls. -3. A **webhook signing secret** (`whsec_...`) from the dashboard to verify +3. A **webhook secret** (`whsec_...`) from the dashboard to verify webhook payloads. 4. Webhooks configured to subscribe to `commentCreated`, `commentReactionAdded`, and `commentReactionRemoved` events. @@ -53,7 +53,7 @@ const adapter = createLiveblocksAdapter({ Liveblocks secret key (`sk_...`) for REST API calls. - Webhook signing secret (`whsec_...`) from the dashboard. + Webhook secret (`whsec_...`) from the dashboard. User ID used when the bot creates, edits, or reacts to comments. Should diff --git a/docs/pages/api-reference/liveblocks-node.mdx b/docs/pages/api-reference/liveblocks-node.mdx index 60c4552f8f6..6518a6df91f 100644 --- a/docs/pages/api-reference/liveblocks-node.mdx +++ b/docs/pages/api-reference/liveblocks-node.mdx @@ -4024,7 +4024,7 @@ within your product, allowing you to react to Liveblocks events as they happen. The `WebhookHandler` class is a helper to handle webhook requests from Liveblocks. -It’s initialized with a signing secret that you can find in your project’s +It’s initialized with a webhook secret that you can find in your project’s webhook page. ```js diff --git a/docs/pages/collaboration-features/ai-collaboration.mdx b/docs/pages/collaboration-features/ai-collaboration.mdx index 26842297015..dccbdd573dc 100644 --- a/docs/pages/collaboration-features/ai-collaboration.mdx +++ b/docs/pages/collaboration-features/ai-collaboration.mdx @@ -239,7 +239,7 @@ n8n node, allowing you to add messages to feeds, show presence, update multiplayer state, and more. ## API Reference diff --git a/docs/pages/integrations.mdx b/docs/pages/integrations.mdx new file mode 100644 index 00000000000..8d57a72d3c1 --- /dev/null +++ b/docs/pages/integrations.mdx @@ -0,0 +1,133 @@ +--- +meta: + title: "Integrations" + description: + "Connect Liveblocks to databases, workflow automation, AI tools, frameworks, + and other products your team uses." +--- + +Liveblocks integrates with products and services your team already uses, +including databases, workflow automation, deployment platforms, AI-native +editors, and other tools and frameworks you combine with realtime collaboration. + +## AI tools + +Develop Liveblocks apps more easily with our agent skills and MCP server for +your favorite tools. + + + } + description="Add our agent skills and MCP server to Cursor." + /> + } + description="Add our agent skills and MCP server to OpenAI Codex." + /> + } + description="Add our agent skills and MCP server to Claude Code." + /> + } + description="Add our agent skills and MCP server to Claude Desktop." + /> + + +## Databases + +Liveblocks doesn’t require a database, but you can mirror your data for +searching, logging, and more. + + + } + title="Supabase" + href="/docs/integrations/supabase" + description="Mirror Storage, Yjs, Comments, and Threads into Supabase Postgres." + /> + } + title="Neon" + href="/docs/integrations/neon" + description="Mirror Storage, Yjs, Comments, and Threads into Neon Postgres." + /> + } + title="PlanetScale" + href="/docs/integrations/planetscale" + description="Mirror Storage, Yjs, Comments, and Threads into PlanetScale MySQL." + /> + + +## App builders + +Add Liveblocks realtime collaboration to your AI app builder projects. + + + } + description="Realtime collaboration for apps you build or export from Lovable." + /> + } + description="Realtime collaboration for apps you build or export from v0." + /> + } + description="Realtime collaboration for apps you build or export from Bolt." + /> + } + description="Realtime collaboration for apps you build with Replit Agent." + /> + + +## Workflow automation + +Use Liveblocks REST API endpoints in UI workflow tools. + + + } + description="REST API calls and webhooks via Liveblocks nodes in n8n workflows." + /> + + +## Build your own integration + +Use [webhooks](/docs/platform/webhooks) and the +[REST API](/docs/api-reference/rest-api-endpoints) to connect Liveblocks to +other databases, automation tools, app builders, or internal systems. If you’d +like to see an integration guide that is not currently available, +[let us know on Discord](https://liveblocks.io/discord). diff --git a/docs/pages/integrations/_provider-template.mdx b/docs/pages/integrations/_provider-template.mdx new file mode 100644 index 00000000000..39aee805f27 --- /dev/null +++ b/docs/pages/integrations/_provider-template.mdx @@ -0,0 +1,109 @@ +--- +meta: + title: "Provider name" + parentTitle: "Integrations" + description: "Use Provider with Liveblocks to..." +--- + +# Provider page template + +Use this file as the starting point for new integration provider pages. Do not +add this file to `docs/routes.json`; copy it to +`docs/pages/integrations/{slug}.mdx` and route that page when the provider is +ready to publish. + +## Route entry + +Add the published provider to the Integrations category in `docs/routes.json`. +Keep the route visible unless the page must be generated without appearing in +navigation. + +```json +{ + "title": "Provider name", + "path": "/integrations/provider-slug", + "keywords": [ + "Provider name", + "provider-slug", + "integration", + "category", + "common product term" + ] +} +``` + +## Metadata + +Use the same frontmatter shape on every provider page. + +```mdx +--- +meta: + title: "Provider name" + parentTitle: "Integrations" + description: + "Use Provider with Liveblocks to add realtime collaboration to..." +--- +``` + +## Required sections + +Each provider page should include these headings so the page is predictable, +searchable, and easy to review. + +## What it enables + +Explain the integration outcome in product terms. Name the Liveblocks features +the provider unlocks or complements, and say whether the page is a ready-to-use +integration, an implementation pattern, a marketplace listing, or partner +submission prep. + +## When to use Liveblocks with Provider + +Describe the best-fit use cases and the boundary between Liveblocks and the +provider. + +## Recommended architecture + +Show which system owns authentication, durable data, realtime collaboration, +workflow automation, deployment, or generated code. Use a table when the split +is important. + +If the page needs a diagram, use a Mermaid code fence. Keep labels short and +describe system boundaries, not every implementation detail. + +```mermaid +graph TD + A[User action] --> B[Liveblocks feature] + B --> C[Webhook or REST API] + C --> D[Your app endpoint] + D --> E[Provider API or database] +``` + +## Setup + +Use `Steps`, `Step`, `StepTitle`, and `StepContent` for implementation steps. +Include environment variables, install commands, auth setup, provider setup, and +the first Liveblocks feature to add. + +## Examples and templates + +Link to runnable examples, starter kits, partner templates, marketplace entries, +or closest existing Liveblocks examples. + +## Limitations and troubleshooting + +Document known constraints, rate limits, eventual consistency, permissions, +secret handling, provider-specific gotchas, and when the provider should not be +treated as the Liveblocks source of truth. + +## Partner listing notes + +Record marketplace submission copy, category recommendations, listing URLs, +owner notes, and any provider-specific requirements. + +## Related docs + +Link to the most relevant Liveblocks docs, such as Authentication, REST API, +Webhooks, Comments, Notifications, Multiplayer, AI Copilots, MCP server, or n8n +nodes. diff --git a/docs/pages/integrations/bolt.mdx b/docs/pages/integrations/bolt.mdx new file mode 100644 index 00000000000..dd4bfffa87c --- /dev/null +++ b/docs/pages/integrations/bolt.mdx @@ -0,0 +1,70 @@ +--- +meta: + title: "Bolt + Liveblocks" + parentTitle: "Integrations" + description: + "Add Liveblocks to apps built or exported from Bolt so you can ship realtime + presence, multiplayer editors, and comments alongside generated UI." +--- + +[Bolt](https://bolt.new/) helps you generate full-stack apps quickly using AI +chats. With Liveblocks, you can add realtime collaboration to your generated +Bolt app, such as +[collaborative text editing](/docs/collaboration-features/multiplayer/text-editor), +[multiplayer documents](/docs/collaboration-features/multiplayer/sync-engine), +[comment threads](/docs/collaboration-features/comments), +[inbox notifications](/docs/collaboration-features/notifications), and +[AI copilots](/docs/collaboration-features/ai-copilots). + +## Setup + + + + + Ask the chat to build with Liveblocks + + Add Liveblocks to your project by asking the chat to add collaborative features, for example: + + ```text title="Example prompt" + Add a realtime text editor with Liveblocks and Tiptap. + ``` + + + To find more ways to use Liveblocks, visit our [showcase](/showcase) and read our [get started guides](/docs/get-started). + + + + + + + Insert your secret key + + During the process, Bolt will prompt you to + insert your Liveblocks secret key from the [dashboard](/dashboard/apikeys). + Paste in your project’s key. + + ```text title="Secret key" + {{SECRET_KEY}} + ``` + + To manually edit your key in Bolt, go to Settings → Secrets → + `LIVEBLOCKS_SECRET_KEY`. + + + + + + Collaboration is ready + + Your app should now have live collaboration—use the chat to continue building your Liveblocks app. + + + + + +## Limitations and troubleshooting + +### Secret or public key issues + +To fix issues related to API keys, instruct Bolt to use a secret key instead of +a public key, and authenticate your Liveblocks application. diff --git a/docs/pages/integrations/claude-code.mdx b/docs/pages/integrations/claude-code.mdx new file mode 100644 index 00000000000..60b548a29d7 --- /dev/null +++ b/docs/pages/integrations/claude-code.mdx @@ -0,0 +1,130 @@ +--- +meta: + title: "Claude Code + Liveblocks" + parentTitle: "Integrations" + description: + "Use Claude Code with Liveblocks agent skills and the MCP server to build + multiplayer apps with guided best practices." +--- + +Use [Claude Code](https://www.anthropic.com/claude-code) with Liveblocks to add +collaborative features to your app. Install +[agent skills](/docs/tools/agent-skills) so your assistant follows Liveblocks +and Yjs guidance, and use our [MCP server](/docs/tools/mcp-server) to allow AI +to inspect and modify your data, such as rooms, Storage, Yjs, comments, and +more. + + + +## Setup + + + + Install agent skills + + To help AI follow best practices in your app, add [Liveblocks agent skills](/docs/tools/agent-skills) + to your system. Make sure to select Claude Code in the CLI. Global installation is easiest. + + ```bash + npx skills add liveblocks/skills + ``` + + + + + + + Install MCP server + + To allow AI to inspect and modify data in your project, install the + [Liveblocks MCP server](/docs/tools/mcp-server). Run the following command + in the terminal, inserting your secret key from + [your dashboard](/dashboard): + + ```bash + claude mcp add liveblocks -e LIVEBLOCKS_SECRET_KEY="{{SECRET_KEY}}" -- npx -y github:liveblocks/liveblocks-mcp-server + ``` + + + Do not use a secret key from a production project, as AI will have direct access to delete data. + + + + + + + + Get help from your AI assistant + + You can now use your AI assistant to help you structure and debug your Liveblocks application. + Here are a few examples. + + > Q: Set up a Liveblocks room on this page. + > + > A: _Certainly, I've set up a Liveblocks room on this page using `RoomProvider`, it has…_ + +
+ + > Q: How many rooms are there? + > + > A: _There are 10 rooms, the last was created 7 minutes ago. Its room ID is `l8Gaj9` and…_ + +
+ + > Q: Add placeholder comments to the `l8Gaj9` room. + > + > A: _I've filled the room with example commands and threads, following your instructions._ +
+ +
+
+ +## More information + +### Agent skills + +Two agent skills are available to your assistant, `liveblocks-best-practices` +and `yjs-best-practices`. These are collections of markdown files that detail +various best practices for using Liveblocks and Yjs. We always recommend using +these skills when building, debugging, or answering questions about Liveblocks +and Yjs. + + + +### MCP server + +Most Liveblocks [REST API](/docs/api-reference/rest-api-endpoints) operations as +tools, so your AI can inspect and edit rooms and data from the editor. This is +helpful for fetching data when debugging, and also useful for creating +placeholder content in your development app, for example you can ask AI to +create new rooms and add placeholder comments and data. + +Each Liveblocks project has a unique secret key, which you pass when installing +the MCP server. Only data from this project can be inspected. Never use a secret +key from a production project, as giving AI direct access would be dangerous, +allowing it to delete your production data. + + + +## Limitations and troubleshooting + +### Skills do not load + +Re-run `npx skills add liveblocks/skills` from the repo root. Ensure Claude Code +can see the generated plugin files. + +### MCP returns auth errors + +Use a secret key from the same [Liveblocks project](/dashboard) as your app. +Confirm `LIVEBLOCKS_SECRET_KEY` in the MCP config matches that project. + +### MCP returns incorrect data + +Check that you’re using the correct secret key for your current project. Try +uninstalling and reinstalling with the correct key. + +## Related docs + +- [Agent skills](/docs/tools/agent-skills). +- [MCP server](/docs/tools/mcp-server). +- [REST API reference](/docs/api-reference/rest-api-endpoints). diff --git a/docs/pages/integrations/claude-desktop.mdx b/docs/pages/integrations/claude-desktop.mdx new file mode 100644 index 00000000000..db861c998e1 --- /dev/null +++ b/docs/pages/integrations/claude-desktop.mdx @@ -0,0 +1,144 @@ +--- +meta: + title: "Claude Desktop + Liveblocks" + parentTitle: "Integrations" + description: + "Use Claude Desktop with Liveblocks agent skills and the MCP server to + inspect and modify your project with AI." +--- + +Use [Claude Desktop](https://claude.ai/download) with Liveblocks to add +collaborative features to your app. Install +[agent skills](/docs/tools/agent-skills) so your assistant follows Liveblocks +and Yjs guidance, and use our [MCP server](/docs/tools/mcp-server) to allow AI +to inspect and modify your data, such as rooms, Storage, Yjs, comments, and +more. + + + +## Setup + + + + Install agent skills + + To help AI follow best practices in your app, add [Liveblocks agent skills](/docs/tools/agent-skills) + to your system. Make sure to select Claude Desktop in the CLI. Global installation is easiest. + + ```bash + npx skills add liveblocks/skills + ``` + + + + + + + Install MCP server + + To allow AI to inspect and modify data in your project, install the + [Liveblocks MCP server](/docs/tools/mcp-server). + + 1. In Claude Desktop, go to Settings → Developer → Edit Config. + 2. Open the JSON file, `claude_desktop_config.json`. + 3. Add the following JSON, inserting your secret key from + [your dashboard](/dashboard): + + ```json + { + "mcpServers": { + "liveblocks": { + "command": "npx", + "args": ["-y", "github:liveblocks/liveblocks-mcp-server"], + "env": { + "LIVEBLOCKS_SECRET_KEY": "{{SECRET_KEY}}" + } + } + } + } + ``` + + + Do not use a secret key from a production project, as AI will have direct access to delete data. + + + + + + + + Get help from your AI assistant + + You can now use your AI assistant to help you structure and debug your Liveblocks application. + Here are a few examples. + + > Q: Set up a Liveblocks room on this page. + > + > A: _Certainly, I've set up a Liveblocks room on this page using `RoomProvider`, it has…_ + +
+ + > Q: How many rooms are there? + > + > A: _There are 10 rooms, the last was created 7 minutes ago. Its room ID is `l8Gaj9` and…_ + +
+ + > Q: Add placeholder comments to the `l8Gaj9` room. + > + > A: _I've filled the room with example commands and threads, following your instructions._ +
+ +
+
+ +## More information + +### Agent skills + +Two agent skills are available to your assistant, `liveblocks-best-practices` +and `yjs-best-practices`. These are collections of markdown files that detail +various best practices for using Liveblocks and Yjs. We always recommend using +these skills when building, debugging, or answering questions about Liveblocks +and Yjs. + + + +### MCP server + +Most Liveblocks [REST API](/docs/api-reference/rest-api-endpoints) operations as +tools, so your AI can inspect and edit rooms and data from Claude Desktop. This +is helpful for fetching data when debugging, and also useful for creating +placeholder content in your development app, for example you can ask AI to +create new rooms and add placeholder comments and data. + +Each Liveblocks project has a unique secret key, which you pass when installing +the MCP server. Only data from this project can be inspected. Never use a secret +key from a production project, as giving AI direct access would be dangerous, +allowing it to delete your production data. + + + +## Limitations and troubleshooting + +### Skills do not load + +Re-run `npx skills add liveblocks/skills` and ensure Claude Desktop is selected +in the CLI. Restart Claude Desktop after installation. + +### MCP returns auth errors + +Use a secret key from the same [Liveblocks project](/dashboard) as your app. +Confirm `LIVEBLOCKS_SECRET_KEY` in `claude_desktop_config.json` matches that +project. + +### MCP returns incorrect data + +Check that you’re using the correct secret key for your current project. Try +uninstalling and reinstalling with the correct key. + +## Related docs + +- [Agent skills](/docs/tools/agent-skills). +- [MCP server](/docs/tools/mcp-server). +- [REST API reference](/docs/api-reference/rest-api-endpoints). diff --git a/docs/pages/integrations/codex.mdx b/docs/pages/integrations/codex.mdx new file mode 100644 index 00000000000..c6fcfa9e99f --- /dev/null +++ b/docs/pages/integrations/codex.mdx @@ -0,0 +1,137 @@ +--- +meta: + title: "OpenAI Codex + Liveblocks" + parentTitle: "Integrations" + description: + "Use OpenAI Codex with Liveblocks agent skills and the MCP server to build + collaborative apps with guided best practices." +--- + +Use [OpenAI Codex](https://openai.com/codex/) with Liveblocks to add +collaborative features to your app. Install +[agent skills](/docs/tools/agent-skills) so your assistant follows Liveblocks +and Yjs guidance, and use our [MCP server](/docs/tools/mcp-server) to allow AI +to inspect and modify your data, such as rooms, Storage, Yjs, comments, and +more. + + + +## Setup + + + + Install agent skills + + To help AI follow best practices in your app, add [Liveblocks agent skills](/docs/tools/agent-skills) + to your system. Make sure to select Codex in the CLI. Global installation is easiest. + + ```bash + npx skills add liveblocks/skills + ``` + + + + + + + Install MCP server + + To allow AI to inspect and modify data in your project, first ensure the Codex CLI is installed: + + ```bash + npm i -g @openai/codex + ``` + + Next, install the + [Liveblocks MCP server](/docs/tools/mcp-server), inserting your secret key + from [your dashboard](/dashboard): + + ```bash + codex mcp add liveblocks \ + --env LIVEBLOCKS_SECRET_KEY="{{SECRET_KEY}}" \ + -- npx -y github:liveblocks/liveblocks-mcp-server + ``` + + + Do not use a secret key from a production project, as AI will have direct access to delete data. + + + + + + + + Get help from your AI assistant + + You can now use your AI assistant to help you structure and debug your Liveblocks application. + Here are a few examples. + + > Q: Set up a Liveblocks room on this page. + > + > A: _Certainly, I've set up a Liveblocks room on this page using `RoomProvider`, it has…_ + +
+ + > Q: How many rooms are there? + > + > A: _There are 10 rooms, the last was created 7 minutes ago. Its room ID is `l8Gaj9` and…_ + +
+ + > Q: Add placeholder comments to the `l8Gaj9` room. + > + > A: _I've filled the room with example commands and threads, following your instructions._ +
+ +
+
+ +## More information + +### Agent skills + +Two agent skills are available to your assistant, `liveblocks-best-practices` +and `yjs-best-practices`. These are collections of markdown files that detail +various best practices for using Liveblocks and Yjs. We always recommend using +these skills when building, debugging, or answering questions about Liveblocks +and Yjs. + + + +### MCP server + +Most Liveblocks [REST API](/docs/api-reference/rest-api-endpoints) operations as +tools, so your AI can inspect and edit rooms and data from the editor. This is +helpful for fetching data when debugging, and also useful for creating +placeholder content in your development app, for example you can ask AI to +create new rooms and add placeholder comments and data. + +Each Liveblocks project has a unique secret key, which you pass when installing +the MCP server. Only data from this project can be inspected. Never use a secret +key from a production project, as giving AI direct access would be dangerous, +allowing it to delete your production data. + + + +## Limitations and troubleshooting + +### Skills do not load + +Re-run `npx skills add liveblocks/skills` from the repo root. Ensure Codex can +see the generated plugin files. + +### MCP returns auth errors + +Use a secret key from the same [Liveblocks project](/dashboard) as your app. +Confirm `LIVEBLOCKS_SECRET_KEY` in the MCP config matches that project. + +### MCP returns incorrect data + +Check that you’re using the correct secret key for your current project. Try +uninstalling and reinstalling with the correct key. + +## Related docs + +- [Agent skills](/docs/tools/agent-skills). +- [MCP server](/docs/tools/mcp-server). +- [REST API reference](/docs/api-reference/rest-api-endpoints). diff --git a/docs/pages/integrations/cursor.mdx b/docs/pages/integrations/cursor.mdx new file mode 100644 index 00000000000..4573336fffb --- /dev/null +++ b/docs/pages/integrations/cursor.mdx @@ -0,0 +1,141 @@ +--- +meta: + title: "Cursor + Liveblocks" + parentTitle: "Integrations" + description: + "Use Cursor with Liveblocks agent skills and the MCP server to build + multiplayer apps with guided best practices." +--- + +Use [Cursor](https://cursor.com/) with Liveblocks to add collaborative features +to your app. Install [agent skills](/docs/tools/agent-skills) so your assistant +follows Liveblocks and Yjs guidance, and use our +[MCP server](/docs/tools/mcp-server) to allow AI to inspect and modify your +data, such as rooms, Storage, Yjs, comments, and more. + + + +## Setup + + + + Install agent skills + + To help AI follow best practices in your app, add [Liveblocks agent skills](/docs/tools/agent-skills) + to your system. Make sure to select Cursor in the CLI. Global installation is easiest. + + ```bash + npx skills add liveblocks/skills + ``` + + + + + + + Install MCP server + + To allow AI to inspect and modify data in your project, install the + [Liveblocks MCP server](/docs/tools/mcp-server). + + 1. Go to File → Cursor Settings → MCP → Add new server. + 2. Add the following JSON, inserting your secret key from + [your dashboard](/dashboard): + + ```json + { + "mcpServers": { + "liveblocks": { + "command": "npx", + "args": ["-y", "github:liveblocks/liveblocks-mcp-server"], + "env": { + "LIVEBLOCKS_SECRET_KEY": "{{SECRET_KEY}}" + } + } + } + } + ``` + + + Do not use a secret key from a production project, as AI will have direct access to delete data. + + + + + + + + Get help from your AI assistant + + You can now use your AI assistant to help you structure and debug your Liveblocks application. + Here are a few examples. + + > Q: Set up a Liveblocks room on this page. + > + > A: _Certainly, I've set up a Liveblocks room on this page using `RoomProvider`, it has…_ + +
+ + > Q: How many rooms are there? + > + > A: _There are 10 rooms, the last was created 7 minutes ago. Its room ID is `l8Gaj9` and…_ + +
+ + > Q: Add placeholder comments to the `l8Gaj9` room. + > + > A: _I've filled the room with example commands and threads, following your instructions._ +
+ +
+
+ +## More information + +### Agent skills + +Two agent skills are available to your assistant, `liveblocks-best-practices` +and `yjs-best-practices`. These are collections of markdown files that detail +various best practices for using Liveblocks and Yjs. We always recommend using +these skills when building, debugging, or answering questions about Liveblocks +and Yjs. + + + +### MCP server + +Most Liveblocks [REST API](/docs/api-reference/rest-api-endpoints) operations as +tools, so your AI can inspect and edit rooms and data from the editor. This is +helpful for fetching data when debugging, and also useful for creating +placeholder content in your development app, for example you can ask AI to +create new rooms and add placeholder comments and data. + +Each Liveblocks project has a unique secret key, which you pass when installing +the MCP server. Only data from this project can be inspected. Never use a secret +key from a production project, as giving AI direct access would be dangerous, +allowing it to delete your production data. + + + +## Limitations and troubleshooting + +### Skills do not load + +Re-run `npx skills add liveblocks/skills` from the repo root. Ensure Cursor can +see the generated plugin files. + +### MCP returns auth errors + +Use a secret key from the same [Liveblocks project](/dashboard) as your app. +Confirm `LIVEBLOCKS_SECRET_KEY` in the MCP config matches that project. + +### MCP returns incorrect data + +Check that you’re using the correct secret key for your current project. Try +uninstalling and reinstalling with the correct key. + +## Related docs + +- [Agent skills](/docs/tools/agent-skills). +- [MCP server](/docs/tools/mcp-server). +- [REST API reference](/docs/api-reference/rest-api-endpoints). diff --git a/docs/pages/integrations/lovable.mdx b/docs/pages/integrations/lovable.mdx new file mode 100644 index 00000000000..c46f536135f --- /dev/null +++ b/docs/pages/integrations/lovable.mdx @@ -0,0 +1,70 @@ +--- +meta: + title: "Lovable + Liveblocks" + parentTitle: "Integrations" + description: + "Add Liveblocks to apps built or exported from Lovable so you can ship + realtime presence, multiplayer editors, and comments alongside generated UI." +--- + +[Lovable](https://lovable.dev/) helps you generate full-stack apps quickly using +AI chats. With Liveblocks, you can add realtime collaboration to your generated +Lovable app, such as +[collaborative text editing](/docs/collaboration-features/multiplayer/text-editor), +[multiplayer documents](/docs/collaboration-features/multiplayer/sync-engine), +[comment threads](/docs/collaboration-features/comments), +[inbox notifications](/docs/collaboration-features/notifications), and +[AI copilots](/docs/collaboration-features/ai-copilots). + +## Setup + + + + + Ask the chat to build with Liveblocks + + Add Liveblocks to your project by asking the chat to add collaborative features, for example: + + ```text title="Example prompt" + Add a realtime text editor with Liveblocks and Tiptap. + ``` + + + To find more ways to use Liveblocks, visit our [showcase](/showcase) and read our [get started guides](/docs/get-started). + + + + + + + Insert your secret key + + During the process, Lovable will prompt you to + insert your Liveblocks secret key from the [dashboard](/dashboard/apikeys). + Paste in your project’s key. + + ```text title="Secret key" + {{SECRET_KEY}} + ``` + + To manually edit + your key in Lovable, go to Cloud → Secrets → `LIVEBLOCKS_SECRET_KEY`. + + + + + + Collaboration is ready + + Your app should now have live collaboration—use the chat to continue building your Liveblocks app. + + + + + +## Limitations and troubleshooting + +### Secret or public key issues + +To fix issues related to API keys, instruct Lovable to use a secret key instead +of a public key, and authenticate your Liveblocks application. diff --git a/docs/pages/tools/n8n-nodes.mdx b/docs/pages/integrations/n8n-nodes.mdx similarity index 55% rename from docs/pages/tools/n8n-nodes.mdx rename to docs/pages/integrations/n8n-nodes.mdx index 625af858d22..27e35d54f40 100644 --- a/docs/pages/tools/n8n-nodes.mdx +++ b/docs/pages/integrations/n8n-nodes.mdx @@ -1,17 +1,17 @@ --- meta: - title: "n8n nodes" - parentTitle: "Tools" + title: "n8n + Liveblocks" + parentTitle: "Integrations" description: - "Use Liveblocks n8n nodes to connect Liveblocks to your n8n workflow." + "Use n8n with Liveblocks to call REST API operations and start workflows + from webhook events." --- -n8n is a workflow automation platform that allows you to build agents visually, -and you can install a set of Liveblocks nodes which you can use directly in your -workflow. Each Liveblocks -[REST API endpoint](/docs/api-reference/rest-api-endpoints) has a corresponding -n8n node, allowing you to create rooms, add messages to feeds, update -multiplayer state, and more. +n8n is a workflow automation platform. Use n8n with Liveblocks to call the +[REST API](/docs/api-reference/rest-api-endpoints) from a workflow, or start a +workflow when Liveblocks sends a [webhook](/docs/platform/webhooks). + +
+## Start with a webhook trigger + +The most common workflow starts when something happens in Liveblocks, for +example when a comment is created. + +1. Add **Liveblocks Trigger** to your n8n workflow. +2. Add your **Liveblocks Webhook Signing Secret API** credential. +3. Copy the trigger's webhook URL. +4. In the [Liveblocks dashboard](/dashboard), create a webhook endpoint with + that URL. +5. Subscribe to [`commentCreated`](/docs/platform/webhooks#CommentCreatedEvent), + then run the n8n workflow. + +When a user creates a comment, Liveblocks sends a webhook to n8n and the +workflow starts. Add more n8n nodes after the trigger to send messages, create +tickets, update databases, or call another Liveblocks operation. + ## Operations The package provides two nodes. ### Liveblocks (action node) -Calls the -[Liveblocks REST API](https://liveblocks.io/docs/api-reference/rest-api-endpoints). -Choose a **resource**, then an **operation**. Operations map to the API (rooms, -storage, Yjs, comments, inbox, webhooks-related server flows, etc.). +Calls the [Liveblocks REST API](/docs/api-reference/rest-api-endpoints). Choose +a **resource**, then an **operation**. Operations map to the API. | Resource | What you can do (examples) | | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -65,29 +80,34 @@ storage, Yjs, comments, inbox, webhooks-related server flows, etc.). The node builds requests from the fields you configure in the UI; some endpoints accept raw JSON for advanced bodies (for example JSON Patch or broadcast payloads). Refer to the -[Liveblocks REST API reference](https://liveblocks.io/docs/api-reference/rest-api-endpoints) -for request and response shapes. +[REST API reference](/docs/api-reference/rest-api-endpoints) for request and +response shapes. ### Liveblocks Trigger (webhook) -Starts a workflow when Liveblocks sends a **webhook** to n8n. Configure the -webhook URL from the trigger in your -[Liveblocks dashboard](https://liveblocks.io/dashboard) webhook settings. You -can filter by **event type** or leave the filter empty to receive all supported -types. - -Supported event filters include: `commentCreated`, `commentDeleted`, -`commentEdited`, `notification`, `storageUpdated`, `threadCreated`, -`threadDeleted`, `threadMetadataUpdated`, `userEntered`, `userLeft`, -`yjsUpdate`. The trigger verifies the request using your **webhook signing -secret** before running the workflow. +Starts a workflow when Liveblocks sends a [webhook](/docs/platform/webhooks) to +n8n. Configure the webhook URL from the trigger in your +[Liveblocks dashboard](/dashboard) webhook settings. You can filter by **event +type** or leave the filter empty to receive all supported types. + +Supported event filters include +[`commentCreated`](/docs/platform/webhooks#CommentCreatedEvent), +[`commentDeleted`](/docs/platform/webhooks#CommentDeletedEvent), +[`commentEdited`](/docs/platform/webhooks#CommentEditedEvent), `notification`, +[`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent), +[`threadCreated`](/docs/platform/webhooks#ThreadCreatedEvent), +[`threadDeleted`](/docs/platform/webhooks#ThreadDeletedEvent), +[`threadMetadataUpdated`](/docs/platform/webhooks#ThreadMetadataUpdatedEvent), +[`userEntered`](/docs/platform/webhooks#UserEnteredEvent), +[`userLeft`](/docs/platform/webhooks#UserLeftEvent), and +[`ydocUpdated`](/docs/platform/webhooks#YDocUpdatedEvent). The trigger verifies +the request using your **webhook secret** before running the workflow. ## Credentials ### Liveblocks API (required for the Liveblocks action node) -1. Create or open a project in the - [Liveblocks dashboard](https://liveblocks.io/dashboard). +1. Create or open a project in the [Liveblocks dashboard](/dashboard). 2. Copy the **secret key** (`sk_…`) from project settings. 3. In n8n, create a credential of type **Liveblocks API** and paste the secret key. @@ -95,10 +115,10 @@ secret** before running the workflow. The credential test calls the REST API (for example listing rooms) to confirm the key works. -### Liveblocks Webhook Signing Secret (required for Liveblocks Trigger) +### Liveblocks Webhook Secret (required for Liveblocks Trigger) 1. In the Liveblocks dashboard, open your project’s **webhook** configuration - and copy the **signing secret** (`whsec_…`). + and copy the **webhook secret** (`whsec_…`). 2. In n8n, create a credential of type **Liveblocks Webhook Signing Secret API** and paste that value. @@ -118,18 +138,46 @@ with your n8n version and this package version. ## Usage -- **Action node**: Add **Liveblocks**, select **resource** and **operation**, - then fill the parameters. Map data from previous nodes into room IDs, user - IDs, and bodies as needed. Use **Execute step** while designing to inspect API - responses and errors. -- **Trigger**: Add **Liveblocks Trigger**, set credentials, copy the **webhook - URL** into the Liveblocks dashboard, and choose which events to listen for. - Use n8n’s test URL while building, then switch to the production URL when the - workflow is active. -- **Errors**: Failed API calls surface as n8n errors with HTTP status and - message when the API returns them. If webhooks fail verification, check that - the signing secret matches the project and that the request is actually from - Liveblocks. +### Call a Liveblocks operation + +Add **Liveblocks**, select a **resource** and **operation**, then fill in the +parameters. Map data from previous nodes into room IDs, user IDs, and request +bodies as needed. + +Use **Execute step** while designing to inspect API responses and errors. + +### Start from a Liveblocks event + +Add **Liveblocks Trigger**, set credentials, copy the **webhook URL** into the +[Liveblocks dashboard](/dashboard), and choose which events to listen for. + +Use n8n's test URL while building, then switch to the production URL when the +workflow is active. + +## Troubleshooting + +### API credential fails + +Check that the credential uses a Liveblocks secret key that starts with `sk_`. +Use the key from the same project whose rooms, threads, or notifications the +workflow should access. + +### Trigger does not run + +Check that the webhook endpoint in the [Liveblocks dashboard](/dashboard) uses +the n8n trigger URL. If you are testing, use the test URL while the workflow is +listening. For active workflows, use the production URL. + +### Webhook verification fails + +Check that the trigger credential uses the webhook secret that starts with +`whsec_`. This is different from your Liveblocks API secret key. + +### API operation fails + +Failed API calls surface as n8n errors with HTTP status and message when the API +returns them. Check the selected resource, operation, room ID, user ID, and JSON +body against the [REST API reference](/docs/api-reference/rest-api-endpoints). New to n8n? See [Try it out](https://docs.n8n.io/try-it-out/) in the n8n docs. diff --git a/docs/pages/integrations/neon.mdx b/docs/pages/integrations/neon.mdx new file mode 100644 index 00000000000..3d99626eaee --- /dev/null +++ b/docs/pages/integrations/neon.mdx @@ -0,0 +1,271 @@ +--- +meta: + title: "Neon + Liveblocks" + parentTitle: "Integrations" + description: + "Use Neon with Liveblocks when your collaborative app needs to store data in + a Postgres database—for example mirrored collaboration data for reporting, + search, audit logs, and workflows." +--- + +[Neon](https://neon.tech/) provides serverless Postgres with branching and +autoscaling. Using webhooks, you can set up one-way synchronization of your +Liveblocks data to Neon for reporting, search, audit logs, or app workflows. + + + +## How data sync works + +Liveblocks [webhooks](/docs/platform/webhooks) trigger when certain events +happen, such as when a collaborative document updates. Liveblocks can trigger an +endpoint in your back end, and from here, you can fetch the latest data and +write it to Neon. Here’s an example of how it works with +[Liveblocks Storage](/docs/collaboration-features/multiplayer/sync-engine/liveblocks-storage). + +```mermaid +sequenceDiagram + actor User + participant LB as Liveblocks app + participant Webhook as Webhook endpoint + participant Neon + + User->>LB: Edits document + Note over LB: Throttle + LB->>Webhook: **storageUpdated** webhook + Webhook->>LB: **getStorageDocument** API + LB-->>Webhook: Storage data + Webhook->>Neon: Upsert row data + Neon-->>Webhook: 200 OK +``` + +## Which data can be synced? + +Various types of Liveblocks data can be synched to Neon with webhooks. + +| Name | Description | Relevant webhook | Relevant API | +| ------------------------ | ------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| Rooms | Created rooms and metadata. | [`roomUpdated`](/docs/platform/webhooks#RoomUpdatedEvent) | [`getRoom`](/docs/api-reference/liveblocks-node#get-rooms-roomId) | +| Active users | Currently connected users. | [`userEntered`](/docs/platform/webhooks#UserEnteredEvent) | [`getActiveUsers`](/docs/api-reference/liveblocks-node#get-active-users) | +| Liveblocks Storage | Custom realtime document state. | [`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent) | [`getStorageDocument`](/docs/api-reference/liveblocks-node#get-rooms-roomId-storage) | +| React Flow | Flowchart state. | [`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent) | [`mutateFlow`](/docs/api-reference/liveblocks-react-flow#mutateFlow) | +| Yjs | `Y.Doc` document state. | [`ydocUpdated`](/docs/platform/webhooks#YDocUpdatedEvent) | [`getYjsDocument`](/docs/api-reference/liveblocks-node#get-rooms-roomId-ydoc) | +| Tiptap/BlockNote/Lexical | Text editor state. | [`ydocUpdated`](/docs/platform/webhooks#YDocUpdatedEvent) | [`getYjsDocument`](/docs/api-reference/liveblocks-node#get-rooms-roomId-ydoc) | +| Threads | Comments, reactions, more. | [`threadCreated`](/docs/platform/webhooks#ThreadCreatedEvent) | [`getThread`](/docs/api-reference/liveblocks-node#get-rooms-roomId-threads-threadId) | + + + This is not an exhaustive list—around [15 related webhook + events](/docs/platform/webhooks#Liveblocks-events) are available, along with + many [Node.js methods](/docs/api-reference/liveblocks-node), [Python + functions](/docs/api-reference/liveblocks-python), and [REST API + endpoints](/docs/api-reference/rest-api-endpoints). + + +## Setup + +Quickstart for synching Liveblocks data to Neon. In this example, we sync +Liveblocks Storage data to Neon, but you can use the same pattern with other +APIs and webhooks to sync other types of data. + + + + Create the Neon table + + Use one row for each Liveblocks room. + + ```sql + create table liveblocks_documents ( + room_id text primary key, + data jsonb not null, + updated_at timestamptz not null default now() + ); + ``` + + + + + + Create a webhook endpoint + + Add a back end endpoint in your app, for example at + `/api/liveblocks-webhook`. + + ```ts + export async function POST(request: Request) { + const body = await request.json(); + const headers = request.headers; + + // Verify the webhook event, then sync to Neon + // ... + + return new Response(null, { status: 200 }); + } + ``` + + + + + + Subscribe to Storage updates + + In the [Liveblocks dashboard](/dashboard), navigate to the “Webhooks’ page inside a project, + and create a webhook endpoint for your endpoint URL—this requires you to + [host your local project](/docs/guides/how-to-test-webhooks-on-localhost). Subscribe to + [`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent), then copy + the webhook secret. + + + + + + Verify the webhook event + + In your endpoint, using [`WebhookHandler`](/docs/api-reference/liveblocks-node#WebhookHandler), + verify the webhook event with the webhook secret from the dashboard. + + ```ts + import { WebhookHandler } from "@liveblocks/node"; + + const webhookHandler = new WebhookHandler( + process.env.LIVEBLOCKS_WEBHOOK_SECRET! + ); + + export async function POST(request: Request) { + const body = await request.json(); + const headers = request.headers; + + // Verify if this is a real webhook request + // +++ + let event; + try { + event = webhookHandler.verifyRequest({ + headers: headers, + rawBody: JSON.stringify(body), + }); + } catch (err) { + console.error(err); + return new Response("Could not verify webhook call", { status: 400 }); + } + // +++ + + // Sync to Neon + // ... + + return new Response(null, { status: 200 }); + } + ``` + + + + + + Sync Storage to Neon + + Set up your Liveblocks and Neon clients, before fetching the Storage document data with + [`getStorageDocument`](/docs/api-reference/rest-api-endpoints#get-rooms-roomId-storage) and + upserting the Neon row with `on conflict … do update`. + + ```ts + import { Liveblocks, WebhookHandler } from "@liveblocks/node"; + import { neon } from "@neondatabase/serverless"; + + const liveblocks = new Liveblocks({ + secret: process.env.LIVEBLOCKS_SECRET_KEY!, + }); + + const sql = neon(process.env.DATABASE_URL!); + + const webhookHandler = new WebhookHandler( + process.env.LIVEBLOCKS_WEBHOOK_SECRET! + ); + + export async function POST(request: Request) { + const body = await request.json(); + const headers = request.headers; + + // Verify if this is a real webhook request + let event; + try { + event = webhookHandler.verifyRequest({ + headers: headers, + rawBody: JSON.stringify(body), + }); + } catch (err) { + console.error(err); + return new Response("Could not verify webhook call", { status: 400 }); + } + + // +++ + if (event.type === "storageUpdated") { + const { roomId } = event.data; + + // Get Storage document data + const data = await liveblocks.getStorageDocument(roomId, "json"); + + // Upsert into Neon + await sql` + insert into liveblocks_documents (room_id, data, updated_at) + values (${roomId}, ${JSON.stringify(data)}::jsonb, now()) + on conflict (room_id) do update set + data = excluded.data, + updated_at = excluded.updated_at + `; + } + // +++ + + return new Response(null, { status: 200 }); + } + ``` + + + + + + Data sync is set up! + + Your Liveblocks data is now automatically synched to Neon when the webhook event is fired. + + + + +## Limits and troubleshooting + +### Storage or Yjs data is stale + +[`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent) and +[`ydocUpdated`](/docs/platform/webhooks#YDocUpdatedEvent) webhooks are throttled +because collaborative documents can be modified up to 60 times per second. Treat +Neon as an eventually consistent mirror, not as the live editing channel. + +### Webhook verification fails + +Check that `LIVEBLOCKS_WEBHOOK_SECRET` is the webhook secret for the webhook +endpoint that sent the event. Also make sure your endpoint passes the same raw +body string to +[`verifyRequest`](/docs/api-reference/liveblocks-node#verifyRequest) that it +received from Liveblocks. + +### Neon writes fail + +Keep `DATABASE_URL` on the server only. Use a role with permission to write the +mirror tables. If you use Neon’s pooled connection string, follow Neon’s +guidance for serverless and long-running workers. + +### Duplicate writes happen + +Webhook deliveries can be retried. Use `on conflict … do update` upserts with a +stable primary key such as `room_id`, `thread_id`, or `comment_id` so repeated +deliveries update the same row. + +### Liveblocks REST requests fail + +Check that `LIVEBLOCKS_SECRET_KEY` is a secret key from the same Liveblocks +project as the room. If the request still fails, return a non-2xx response so +the webhook can be retried. + +## Related docs + +- [Supabase + Liveblocks](/docs/integrations/supabase). +- API references for, [webhooks](/docs/platform/webhooks), + [Node.js](/docs/api-reference/liveblocks-node), + [Python](/docs/api-reference/liveblocks-python), and + [REST API](/docs/api-reference/rest-api-endpoints). diff --git a/docs/pages/integrations/planetscale.mdx b/docs/pages/integrations/planetscale.mdx new file mode 100644 index 00000000000..62cbe2e6826 --- /dev/null +++ b/docs/pages/integrations/planetscale.mdx @@ -0,0 +1,280 @@ +--- +meta: + title: "PlanetScale + Liveblocks" + parentTitle: "Integrations" + description: + "Use PlanetScale with Liveblocks when your collaborative app needs to store + data in a MySQL database—for example mirrored collaboration data for + reporting, search, audit logs, and workflows." +--- + +[PlanetScale](https://planetscale.com/) provides a serverless MySQL database +with horizontal scaling and branching. Using webhooks, you can set up one-way +synchronization of your Liveblocks data to PlanetScale for reporting, search, +audit logs, or app workflows. + + + +## How data sync works + +Liveblocks [webhooks](/docs/platform/webhooks) trigger when certain events +happen, such as when a collaborative document updates. Liveblocks can trigger an +endpoint in your back end, and from here, you can fetch the latest data and +write it to PlanetScale. Here’s an example of how it works with +[Liveblocks Storage](/docs/collaboration-features/multiplayer/sync-engine/liveblocks-storage). + +```mermaid +sequenceDiagram + actor User + participant LB as Liveblocks app + participant Webhook as Webhook endpoint + participant PlanetScale + + User->>LB: Edits document + Note over LB: Throttle + LB->>Webhook: **storageUpdated** webhook + Webhook->>LB: **getStorageDocument** API + LB-->>Webhook: Storage data + Webhook->>PlanetScale: Upsert row data + PlanetScale-->>Webhook: 200 OK +``` + +## Which data can be synced? + +Various types of Liveblocks data can be synched to PlanetScale with webhooks. + +| Name | Description | Relevant webhook | Relevant API | +| ------------------------ | ------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| Rooms | Created rooms and metadata. | [`roomUpdated`](/docs/platform/webhooks#RoomUpdatedEvent) | [`getRoom`](/docs/api-reference/liveblocks-node#get-rooms-roomId) | +| Active users | Currently connected users. | [`userEntered`](/docs/platform/webhooks#UserEnteredEvent) | [`getActiveUsers`](/docs/api-reference/liveblocks-node#get-active-users) | +| Liveblocks Storage | Custom realtime document state. | [`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent) | [`getStorageDocument`](/docs/api-reference/liveblocks-node#get-rooms-roomId-storage) | +| React Flow | Flowchart state. | [`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent) | [`mutateFlow`](/docs/api-reference/liveblocks-react-flow#mutateFlow) | +| Yjs | `Y.Doc` document state. | [`ydocUpdated`](/docs/platform/webhooks#YDocUpdatedEvent) | [`getYjsDocument`](/docs/api-reference/liveblocks-node#get-rooms-roomId-ydoc) | +| Tiptap/BlockNote/Lexical | Text editor state. | [`ydocUpdated`](/docs/platform/webhooks#YDocUpdatedEvent) | [`getYjsDocument`](/docs/api-reference/liveblocks-node#get-rooms-roomId-ydoc) | +| Threads | Comments, reactions, more. | [`threadCreated`](/docs/platform/webhooks#ThreadCreatedEvent) | [`getThread`](/docs/api-reference/liveblocks-node#get-rooms-roomId-threads-threadId) | + + + This is not an exhaustive list—around [15 related webhook + events](/docs/platform/webhooks#Liveblocks-events) are available, along with + many [Node.js methods](/docs/api-reference/liveblocks-node), [Python + functions](/docs/api-reference/liveblocks-python), and [REST API + endpoints](/docs/api-reference/rest-api-endpoints). + + +## Setup + +Quickstart for synching Liveblocks data to PlanetScale. In this example, we +sync Liveblocks Storage data to PlanetScale, but you can use the same pattern +with other APIs and webhooks to sync other types of data. + + + We have a [full step-by-step guide available + here](/docs/guides/how-to-synchronize-your-liveblocks-storage-document-data-to-a-planetscale-mysql-database), + this page provides a quick summary. + + + + + Create the PlanetScale table + + Use one row for each Liveblocks room. + + ```sql + create table liveblocks_documents ( + room_id varchar(255) primary key, + data json not null, + updated_at timestamp not null default current_timestamp + on update current_timestamp + ); + ``` + + + + + + Create a webhook endpoint + + Add a back end endpoint in your app, for example at + `/api/liveblocks-webhook`. + + ```ts + export async function POST(request: Request) { + const body = await request.json(); + const headers = request.headers; + + // Verify the webhook event, then sync to PlanetScale + // ... + + return new Response(null, { status: 200 }); + } + ``` + + + + + + Subscribe to Storage updates + + In the [Liveblocks dashboard](/dashboard), navigate to the “Webhooks’ page inside a project, + and create a webhook endpoint for your endpoint URL—this requires you to + [host your local project](/docs/guides/how-to-test-webhooks-on-localhost). + Subscribe to + [`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent), then copy + the webhook secret. + + + + + + Verify the webhook event + + In your endpoint, using [`WebhookHandler`](/docs/api-reference/liveblocks-node#WebhookHandler), + verify the webhook event with the webhook secret from the dashboard. + + ```ts + import { WebhookHandler } from "@liveblocks/node"; + + const webhookHandler = new WebhookHandler( + process.env.LIVEBLOCKS_WEBHOOK_SECRET! + ); + + export async function POST(request: Request) { + const body = await request.json(); + const headers = request.headers; + + // Verify if this is a real webhook request + // +++ + let event; + try { + event = webhookHandler.verifyRequest({ + headers: headers, + rawBody: JSON.stringify(body), + }); + } catch (err) { + console.error(err); + return new Response("Could not verify webhook call", { status: 400 }); + } + // +++ + + // Sync to PlanetScale + // ... + + return new Response(null, { status: 200 }); + } + ``` + + + + + + Sync Storage to PlanetScale + + Set up your Liveblocks and PlanetScale clients, before fetching the Storage document data with + [`getStorageDocument`](/docs/api-reference/rest-api-endpoints#get-rooms-roomId-storage) and + upserting the PlanetScale row with `on duplicate key update`. + + ```ts + import { Liveblocks, WebhookHandler } from "@liveblocks/node"; + import { connect } from "@planetscale/database"; + + const liveblocks = new Liveblocks({ + secret: process.env.LIVEBLOCKS_SECRET_KEY!, + }); + + const db = connect({ url: process.env.DATABASE_URL! }); + + const webhookHandler = new WebhookHandler( + process.env.LIVEBLOCKS_WEBHOOK_SECRET! + ); + + export async function POST(request: Request) { + const body = await request.json(); + const headers = request.headers; + + // Verify if this is a real webhook request + let event; + try { + event = webhookHandler.verifyRequest({ + headers: headers, + rawBody: JSON.stringify(body), + }); + } catch (err) { + console.error(err); + return new Response("Could not verify webhook call", { status: 400 }); + } + + // +++ + if (event.type === "storageUpdated") { + const { roomId } = event.data; + + // Get Storage document data + const data = await liveblocks.getStorageDocument(roomId, "json"); + + // Upsert into PlanetScale + await db.execute( + `insert into liveblocks_documents (room_id, data) + values (?, ?) + on duplicate key update data = values(data)`, + [roomId, JSON.stringify(data)] + ); + } + // +++ + + return new Response(null, { status: 200 }); + } + ``` + + + + + + Data sync is set up! + + Your Liveblocks data is now automatically synched to PlanetScale when the webhook event is fired. + + + + +## Limits and troubleshooting + +### Storage or Yjs data is stale + +[`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent) and +[`ydocUpdated`](/docs/platform/webhooks#YDocUpdatedEvent) webhooks are throttled +because collaborative documents can be modified up to 60 times per second. Treat +PlanetScale as an eventually consistent mirror, not as the live editing channel. + +### Webhook verification fails + +Check that `LIVEBLOCKS_WEBHOOK_SECRET` is the webhook secret for the webhook +endpoint that sent the event. Also make sure your endpoint passes the same raw +body string to +[`verifyRequest`](/docs/api-reference/liveblocks-node#verifyRequest) that it +received from Liveblocks. + +### PlanetScale writes fail + +Keep `DATABASE_URL` on the server only. Use a database password with permission +to write the mirror tables. PlanetScale doesn’t support foreign keys by +default—if you need referential integrity, model it in application code. + +### Duplicate writes happen + +Webhook deliveries can be retried. Use `on duplicate key update` upserts with a +stable primary key such as `room_id`, `thread_id`, or `comment_id` so repeated +deliveries update the same row. + +### Liveblocks REST requests fail + +Check that `LIVEBLOCKS_SECRET_KEY` is a secret key from the same Liveblocks +project as the room. If the request still fails, return a non-2xx response so +the webhook can be retried. + +## Related docs + +- [Synchronize Liveblocks Storage document data to PlanetScale MySQL](/docs/guides/how-to-synchronize-your-liveblocks-storage-document-data-to-a-planetscale-mysql-database). +- [Synchronize Liveblocks Yjs document data to PlanetScale MySQL](/docs/guides/how-to-synchronize-your-liveblocks-yjs-document-data-to-a-planetscale-mysql-database). +- API references for, [webhooks](/docs/platform/webhooks), + [Node.js](/docs/api-reference/liveblocks-node), + [Python](/docs/api-reference/liveblocks-python), and + [REST API](/docs/api-reference/rest-api-endpoints). diff --git a/docs/pages/integrations/replit.mdx b/docs/pages/integrations/replit.mdx new file mode 100644 index 00000000000..bac11b790a0 --- /dev/null +++ b/docs/pages/integrations/replit.mdx @@ -0,0 +1,69 @@ +--- +meta: + title: "Replit + Liveblocks" + parentTitle: "Integrations" + description: + "Add Liveblocks to apps built with Replit Agent so you can ship realtime + presence, multiplayer editors, and comments alongside generated UI." +--- + +[Replit](https://replit.com/) lets you build and run full-stack apps in the +browser using Replit Agent. With Liveblocks, you can add realtime collaboration +to your generated Replit app, such as +[collaborative text editing](/docs/collaboration-features/multiplayer/text-editor), +[multiplayer documents](/docs/collaboration-features/multiplayer/sync-engine), +[comment threads](/docs/collaboration-features/comments), +[inbox notifications](/docs/collaboration-features/notifications), and +[AI copilots](/docs/collaboration-features/ai-copilots). + +## Setup + + + + + Ask the Agent to build with Liveblocks + + Add Liveblocks to your project by asking Replit Agent to add collaborative features, for example: + + ```text title="Example prompt" + Add a realtime text editor with Liveblocks and Tiptap. + ``` + + + To find more ways to use Liveblocks, visit our [showcase](/showcase) and read our [get started guides](/docs/get-started). + + + + + + + Insert your secret key + + During the process, Replit Agent will prompt you to + insert your Liveblocks secret key from the [dashboard](/dashboard/apikeys). + Paste in your project’s key. + + ```text title="Secret key" + {{SECRET_KEY}} + ``` + + To manually edit your key in Replit, go to Tools & Files → Secrets → `LIVEBLOCKS_SECRET_KEY`. + + + + + + Collaboration is ready + + Your app should now have live collaboration—use the Agent to continue building your Liveblocks app. + + + + + +## Limitations and troubleshooting + +### Secret or public key issues + +To fix issues related to API keys, instruct Replit Agent to use a secret key +instead of a public key, and authenticate your Liveblocks application. diff --git a/docs/pages/integrations/supabase.mdx b/docs/pages/integrations/supabase.mdx new file mode 100644 index 00000000000..4892e4b5f91 --- /dev/null +++ b/docs/pages/integrations/supabase.mdx @@ -0,0 +1,279 @@ +--- +meta: + title: "Supabase + Liveblocks" + parentTitle: "Integrations" + description: + "Use Supabase with Liveblocks when your collaborative app needs to store + data in a Postgres database—for example mirrored collaboration data for + reporting, search, audit logs, and workflows." +--- + +[Supabase](https://supabase.com/) provides a Postgres database with a rich set +of features. Using webhooks, you can set up one-way synchronization of your +Liveblocks data to Supabase for reporting, search, audit logs, or app workflows. + + + +## How data sync works + +Liveblocks [webhooks](/docs/platform/webhooks) trigger when certain events +happen, such as when a collaborative document updates. Liveblocks can trigger an +endpoint in your back end, and from here, you can fetch the latest data and +write it to Supabase. Here’s an example of how it works with +[Liveblocks Storage](/docs/collaboration-features/multiplayer/sync-engine/liveblocks-storage). + +```mermaid +sequenceDiagram + actor User + participant LB as Liveblocks app + participant Webhook as Webhook endpoint + participant Supabase + + User->>LB: Edits document + Note over LB: Throttle + LB->>Webhook: **storageUpdated** webhook + Webhook->>LB: **getStorageDocument** API + LB-->>Webhook: Storage data + Webhook->>Supabase: Upsert row data + Supabase-->>Webhook: 200 OK +``` + +## Which data can be synced? + +Various types of Liveblocks data can be synched to Supabase with webhooks. + +| Name | Description | Relevant webhook | Relevant API | +| ------------------------ | ------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| Rooms | Created rooms and metadata. | [`roomUpdated`](/docs/platform/webhooks#RoomUpdatedEvent) | [`getRoom`](/docs/api-reference/liveblocks-node#get-rooms-roomId) | +| Active users | Currently connected users. | [`userEntered`](/docs/platform/webhooks#UserEnteredEvent) | [`getActiveUsers`](/docs/api-reference/liveblocks-node#get-active-users) | +| Liveblocks Storage | Custom realtime document state. | [`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent) | [`getStorageDocument`](/docs/api-reference/liveblocks-node#get-rooms-roomId-storage) | +| React Flow | Flowchart state. | [`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent) | [`mutateFlow`](/docs/api-reference/liveblocks-react-flow#mutateFlow) | +| Yjs | `Y.Doc` document state. | [`ydocUpdated`](/docs/platform/webhooks#YDocUpdatedEvent) | [`getYjsDocument`](/docs/api-reference/liveblocks-node#get-rooms-roomId-ydoc) | +| Tiptap/BlockNote/Lexical | Text editor state. | [`ydocUpdated`](/docs/platform/webhooks#YDocUpdatedEvent) | [`getYjsDocument`](/docs/api-reference/liveblocks-node#get-rooms-roomId-ydoc) | +| Threads | Comments, reactions, more. | [`threadCreated`](/docs/platform/webhooks#ThreadCreatedEvent) | [`getThread`](/docs/api-reference/liveblocks-node#get-rooms-roomId-threads-threadId) | + + + This is not an exhaustive list—around [15 related webhook + events](/docs/platform/webhooks#Liveblocks-events) are available, along with + many [Node.js methods](/docs/api-reference/liveblocks-node), [Python + functions](/docs/api-reference/liveblocks-python), and [REST API + endpoints](/docs/api-reference/rest-api-endpoints). + + +## Setup + +Quickstart for synching Liveblocks data to Supabase. In this example, we sync +Liveblocks Storage data to Supabase, but you can use the same pattern with other +APIs and webhooks to sync other types of data. + + + We have a [full step-by-step guide available + here](/docs/guides/how-to-synchronize-your-liveblocks-storage-document-data-to-a-supabase-postgres-database), + this page provides a quick summary. + + + + + Create the Supabase table + + Use one row for each Liveblocks room. + + ```sql + create table liveblocks_documents ( + room_id text primary key, + data jsonb not null, + updated_at timestamptz not null default now() + ); + ``` + + + + + + Create a webhook endpoint + + Add a back end endpoint in your app, for example at + `/api/liveblocks-webhook`. + + ```ts + export async function POST(request: Request) { + const body = await request.json(); + const headers = request.headers; + + // Verify the webhook event, then sync to Supabase + // ... + + return new Response(null, { status: 200 }); + } + ``` + + + + + + Subscribe to Storage updates + + In the [Liveblocks dashboard](/dashboard), navigate to the “Webhooks’ page inside a project, + and create a webhook endpoint for your endpoint URL—this requires you to + [host your local project](/docs/guides/how-to-test-webhooks-on-localhost). Subscribe to + [`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent), then copy + the webhook secret. + + + + + + Verify the webhook event + + In your endpoint, using [`WebhookHandler`](/docs/api-reference/liveblocks-node#WebhookHandler), + verify the webhook event with the webhook secret from the dashboard. + + ```ts + import { WebhookHandler } from "@liveblocks/node"; + + const webhookHandler = new WebhookHandler( + process.env.LIVEBLOCKS_WEBHOOK_SECRET! + ); + + export async function POST(request: Request) { + const body = await request.json(); + const headers = request.headers; + + // Verify if this is a real webhook request + // +++ + let event; + try { + event = webhookHandler.verifyRequest({ + headers: headers, + rawBody: JSON.stringify(body), + }); + } catch (err) { + console.error(err); + return new Response("Could not verify webhook call", { status: 400 }); + } + // +++ + + // Sync to Supabase + // ... + + return new Response(null, { status: 200 }); + } + ``` + + + + + + Sync Storage to Supabase + + Set up your Liveblocks and Supabase clients, before fetching the Storage document data with + [`getStorageDocument`](/docs/api-reference/rest-api-endpoints#get-rooms-roomId-storage) and + upserting the Supabase row with `upsert`. + + ```ts + import { Liveblocks, WebhookHandler } from "@liveblocks/node"; + import { createClient } from "@supabase/supabase-js"; + + const liveblocks = new Liveblocks({ + secret: process.env.LIVEBLOCKS_SECRET_KEY!, + }); + + const supabase = createClient( + process.env.SUPABASE_URL!, + process.env.SUPABASE_SERVICE_ROLE_KEY! + ); + + const webhookHandler = new WebhookHandler( + process.env.LIVEBLOCKS_WEBHOOK_SECRET! + ); + + export async function POST(request: Request) { + const body = await request.json(); + const headers = request.headers; + + // Verify if this is a real webhook request + let event; + try { + event = webhookHandler.verifyRequest({ + headers: headers, + rawBody: JSON.stringify(body), + }); + } catch (err) { + console.error(err); + return new Response("Could not verify webhook call", { status: 400 }); + } + + // +++ + if (event.type === "storageUpdated") { + const { roomId } = event.data; + + // Get Storage document data + const data = await liveblocks.getStorageDocument(roomId, "json"); + + // Upsert into Supabase + const { error } = await supabase.from("liveblocks_documents").upsert({ + room_id: roomId, + data, + updated_at: new Date().toISOString(), + }); + } + // +++ + + return new Response(null, { status: 200 }); + } + ``` + + + + + + Data sync is set up! + + Your Liveblocks data is now automatically synched to Supabase when the webhook event is fired. + + + + +## Limits and troubleshooting + +### Storage or Yjs data is stale + +[`storageUpdated`](/docs/platform/webhooks#StorageUpdatedEvent) and +[`ydocUpdated`](/docs/platform/webhooks#YDocUpdatedEvent) webhooks are throttled +because collaborative documents can be modified up to 60 times per second. Treat +Supabase as an eventually consistent mirror, not as the live editing channel. + +### Webhook verification fails + +Check that `LIVEBLOCKS_WEBHOOK_SECRET` is the webhook secret for the webhook +endpoint that sent the event. Also make sure your endpoint passes the same raw +body string to +[`verifyRequest`](/docs/api-reference/liveblocks-node#verifyRequest) that it +received from Liveblocks. + +### Supabase writes fail + +Keep the Supabase service role key on the server. If Row Level Security is +enabled on the mirror table, make sure your server client has permission to +write to it. + +### Duplicate writes happen + +Webhook deliveries can be retried. Use `upsert` with a stable primary key such +as `room_id`, `thread_id`, or `comment_id` so repeated deliveries update the +same row. + +### Liveblocks REST requests fail + +Check that `LIVEBLOCKS_SECRET_KEY` is a secret key from the same Liveblocks +project as the room. If the request still fails, return a non-2xx response so +the webhook can be retried. + +## Related docs + +- [Synchronize Liveblocks Storage document data to Supabase Postgres](/docs/guides/how-to-synchronize-your-liveblocks-storage-document-data-to-a-supabase-postgres-database). +- [Synchronize Liveblocks Yjs document data to Supabase Postgres](/docs/guides/how-to-synchronize-your-liveblocks-yjs-document-data-to-a-supabase-postgres-database). +- API references for, [webhooks](/docs/platform/webhooks), + [Node.js](/docs/api-reference/liveblocks-node), + [Python](/docs/api-reference/liveblocks-python), and + [REST API](/docs/api-reference/rest-api-endpoints). diff --git a/docs/pages/integrations/supabase.prompt.md b/docs/pages/integrations/supabase.prompt.md new file mode 100644 index 00000000000..24ca4aaf95c --- /dev/null +++ b/docs/pages/integrations/supabase.prompt.md @@ -0,0 +1,21 @@ +# Liveblocks + Supabase — context for your assistant + +**Purpose:** Help users mirror Liveblocks Storage, Yjs, Comments, and Threads into Supabase Postgres via webhooks and the REST API. + +**Do:** + +- Treat Liveblocks as the source of truth for Storage, Yjs, Comments, and Threads; treat Supabase as an eventually consistent mirror. +- Trigger syncs from `storageUpdated`, `ydocUpdated`, and thread/comment webhooks; fetch current state with the Liveblocks REST API; `upsert` into Supabase. +- Verify webhooks with `WebhookHandler` from `@liveblocks/node`, passing the exact raw body received. +- Use stable primary keys (`room_id`, `thread_id`, `comment_id`) so retried deliveries update the same row. +- Keep the Supabase service role key server-only and confirm RLS allows the server client to write to the mirror table. + +**Do not:** + +- Conflate `LIVEBLOCKS_SECRET_KEY` (REST) with `LIVEBLOCKS_WEBHOOK_SECRET` (signature verification). +- Use `insert` for webhook-driven writes, or omit a stable primary key — duplicates will appear on retry. +- Re-stringify a parsed JSON body before `verifyRequest`; pass the raw body Liveblocks sent. +- Treat Supabase as the live editing channel — `storageUpdated` and `ydocUpdated` are throttled. +- Mirror more Comments or Threads fields than the user's workflow needs. + +Tailor examples to the user's stack (Next.js route handler, Express, etc.) and the specific Liveblocks feature they're syncing. diff --git a/docs/pages/integrations/v0.mdx b/docs/pages/integrations/v0.mdx new file mode 100644 index 00000000000..ec3facfe54d --- /dev/null +++ b/docs/pages/integrations/v0.mdx @@ -0,0 +1,70 @@ +--- +meta: + title: "v0 + Liveblocks" + parentTitle: "Integrations" + description: + "Add Liveblocks to apps built or exported from v0 so you can ship realtime + presence, multiplayer editors, and comments alongside generated UI." +--- + +[v0](https://v0.app/) helps you generate full-stack apps quickly using AI chats. +With Liveblocks, you can add realtime collaboration to your generated v0 app, +such as +[collaborative text editing](/docs/collaboration-features/multiplayer/text-editor), +[multiplayer documents](/docs/collaboration-features/multiplayer/sync-engine), +[comment threads](/docs/collaboration-features/comments), +[inbox notifications](/docs/collaboration-features/notifications), and +[AI copilots](/docs/collaboration-features/ai-copilots). + +## Setup + + + + + Ask the chat to build with Liveblocks + + Add Liveblocks to your project by asking the chat to add collaborative features, for example: + + ```text title="Example prompt" + Add a realtime text editor with Liveblocks and Tiptap. + ``` + + + To find more ways to use Liveblocks, visit our [showcase](/showcase) and read our [get started guides](/docs/get-started). + + + + + + + Insert your secret key + + During the process, v0 will prompt you to + insert your Liveblocks secret key from the [dashboard](/dashboard/apikeys). + Paste in your project’s key. + + ```text title="Secret key" + {{SECRET_KEY}} + ``` + + To manually edit your key in v0, go to Settings → Environment + Variables → `LIVEBLOCKS_SECRET_KEY`. + + + + + + Collaboration is ready + + Your app should now have live collaboration—use the chat to continue building your Liveblocks app. + + + + + +## Limitations and troubleshooting + +### Secret or public key issues + +To fix issues related to API keys, instruct v0 to use a secret key instead of a +public key, and authenticate your Liveblocks application. diff --git a/docs/pages/tools/agent-skills.mdx b/docs/pages/tools/agent-skills.mdx index 9a4225ba1d6..df095f79385 100644 --- a/docs/pages/tools/agent-skills.mdx +++ b/docs/pages/tools/agent-skills.mdx @@ -11,6 +11,8 @@ Create your Liveblocks applications more easily with our agent skills, designed to help AI coding assistants follow best practices for Liveblocks and Yjs. These skills use the [Agent Skills](https://agentskills.io/home) format. + +