Chris Nicholas
@chrisnicholas
Developer experience @liveblocks.io • Interactive articles on chrisnicholas.dev
You can also upload files from the server, handy if you're doing any back-end processing or AI generation. Call the server-side `mutateStorage` method, and each browser will update in real-time with the image.
It's quite simple, there's a new `useUploadFile` hook for uploading a file to a room, then attach the file to your Storage tree. Then fetch your file, and get its URL. You can create a download button, or if it's browser compatible (like an image), render it on the page.
You can now upload files to @liveblocks.io! If your multiplayer app uses media, archives, or any file, `LiveFile` allows you to upload them directly to your Storage tree. Other users will see the file appear in realtime—like in this @tldraw.com clip. Learn more ↓
Article: What's the best vector database for AI and RAG? Turbopuffer, Pinecone, pgvector, more—a deep-dive into the options. Our team's well positioned to give guidance, as we tried them before building our product. Written last year, we stand by our choice! Link ↓
Build a collaborative agentic workflow builder. In CodeWithAntonio's latest video, he explains how to build a browser automation tool—in the video you it automatically loads a news website, extracts headlines, and sends an email. Video tutorial ↓
When rendering your threads, check for `thread.visibility` to render private threads differently, like in the video above.
…the easiest way is to add a group to your room and remove their private comments access, like I'm doing here with `reader`. Then pass the `reader` `groupId` to a user when authenticating, and they won't be able to view private comments!
To create a private thread, pass `visibility: "private"` to `Composer` or `useCreateThread`. To access who can see it, there's a couple of ways to do it…
Using @liveblocks.io Comments? You can now create private comment threads within a room. Set permissions to control exactly who can see and reply—ideal for internal notes and hidden feedback. How to set it up ↓
I've updated my open-source AI slideshow template! It's got a bunch of new features: ✦ Drag-and-drop elements, double-click to edit text. ✦ Editing is collaborative, users have presence. ✦ Multiplayer undo/redo, in both views. ✦ Create multiple slides. Get it ↓
Exporting to powerpoint currently generates a high-res image embedded into a powerpoint file. It looks pixel perfect, as you can see in Google Slides below, but you can't currently edit the text.
Commenting uses @liveblocks.io pre-made React components. You can leave reactions, mention others, and even create a notification inbox for missed comments. Threads are attached to the canvas using a percentage value from the top left, which works well with fixed slide ratio.
The HTML code is stored in Yjs, hosted by @liveblocks.io. Yjs allows you to create multiplayer editing experiences, and in combination with CodeMirror's editor, like in this example, you can write code live with others.
I'm using various @vercel.com parts for the chat! The UI is components from AI Elements, and AI SDK/Gateway power the generation. The messages themselves are stored in @liveblocks feeds. Feeds allow you to store any kind of real-time multiplayer list, such as logs, chats, and more.
I've built an open-source slide editor! ✦ Generate HTML slides with AI. ✦ Collaborative code editing. ✦ Draggable commenting. ✦ Export to powerpoint. Try it out ↓
Add a multiplayer .docx editor to your app! ✦ 100% compatible with MS Word. ✦ Real-time editing and presence. ✦ Leave suggestions for others. Get it ↓
Add a multiplayer AI chat to your app! ✦ Multiple users at once. ✦ Real-time chat updates. ✦ Switch between pages, history. Get it from @vercel.com templates ↓
I've published an AI spreadsheet template. ✦ Cells & chat are real-time multiplayer. ✦ Live presence for humans & agents. ✦ Trigger AI from comment threads. It's open-source ↓
Trying out @nextjs.org 3.16 instant navigations. Adds a noticeable feeling of snappiness 👏 nice. Here's a before → after.
`.insert` isn't the only method, there's also `.move`, `.push`, and 20 others! Plus you get REST APIs, webhooks, DevTools, and more. If you take this to the next level, you can implement real, complex apps, such as multiplayer tldraw, as demonstrated here with our dev server.
And how do you add an object to the list? With a simple mutation. Get `shapes`, and insert a new one. A `LiveObject` is a conflict-resolved object, allowing multiple users to edit it at the same time—changes are merged gracefully together.
DX in @liveblocks.io is crazy! See this hook? It fetches a multiplayer list of objects. Every time the list changes, it automatically updates with a new value, in real-time. No back-end or setting up WebSockets—just React.
In case you missed it, @liveblocks.io has nodes for n8n! It's super handy for setting up complex workflows, for example after a Liveblocks comment's created, you can trigger an AI response. Another use case is allowing AI to modify your realtime data with a custom trigger.
Often, the best way to collaborate with AI is to bring it into your human workplace. Slack bots are great for this, but it doesn't help with editing documents. Inline commenting is ideal; the agent can see both where the comment is placed, and the conversation surrounding it.
AI chats work fairly well, given knowledge and a solid prompt. For example this AI can read table, and understands how to use formulae. Plus, giving AI presence indicators helps users understand which changes are being made. But is a chat always the most natural solution?
For example, how do you handle undo/redo? Pressing undo in this toolbar should only revert your local changes—the AI, and other users, should each have their own undo stacks. You can see this working below, undo doesn't affect the AI's new formatting, it only reverts my typing.
We're transitioning into a world where multiplayer documents are required. As more and more agents become commonplace, you need a way to ensure that their modifications don't disrupt other agents & humans—you need a sync engine, like below. And that's not the only challenge ↓
In React, simply fetch the feed. Each message appears in real-time as it's sent, and you can also update existing messages, helpful for streaming in responses.
When a feed message is added, Liveblocks presence APIs are triggered, allowing you to show what an agent is doing in real-time. It's super easy to hook it up from any workflow, and add presence to your app. On the front-end, get the presence with the `useOthers` hook.