Now that we've developed custom nodes and our node registry, let's go ahead and add live blocks to our project, which will enable live collaboration in each workflow room as well as enable actual data persistence because right now regardless of how many changes we do in a workflow room if we connect some nodes drag them around all of that is reset when you reload the page So we can achieve both by adding live blocks. Creating our own sync engine and live collaboration would take months to implement to this level. But thanks to live blocks, we can achieve all of this in just a few lines of code. Using the link on the screen, you can visit their page. And once you're here, go ahead and create an account.
Once you create an account, go ahead and create a brand new project. I would recommend leaving the environment in development mode so that we can test it out without worrying of incurring any costs. And click create project. Once you've created your account, I would recommend going into their documentation page, get started. In here, let's go ahead and select multiplayer as the collaboration feature we want to set up.
Then let's choose canvases as the type of content people are going to edit. That is going to provide us with several guides. Go ahead and choose React flow with Next.js. In here, you can follow the guide on adding React flow and Liveblocks integration into your app. Before we add this to our project, I would recommend doing one prompt to improve our data.ts file within features workflows.
What's currently missing is the function which is going to fetch an individual workflow scope to the organization ID. So we can run a simple prompt like this. Add a get workflow organization ID and ID as the parameters to our workflows data file that returns the single workflow row matching both ID and organization ID. That should generate a function like this and it should also add an import for the end query from Drizzle ORM. I would recommend staging and committing this change as well as pushing it to the repository so we reduce the amount of uncommitted change we are going to have to review once we add LiveBlocks.
So this is somewhat of a checkpoint for us. Before we add LiveBlocks to our project I would recommend scrolling down until you find tools agent skills and in here you can find the command with which you can install Liveblocks skills which will make our agent more reliable when it comes to using and developing with Liveblocks. So let's go ahead and run this command and choose Liveblocks best practices and go ahead and install this for your agent and select project as the installation scope and use the symbolic link as the installation method. This will once again produce a bunch of uncommitted files so go ahead and do git add, git commit, and then git push, so you start with a clean slate and don't have to review 50 files. Remember to run reload skills and reload window so that you actually have LiveBlocks skill available.
Now that we've prepared our environment for LiveBlocks, let's go ahead and actually add it to our project. Now usually if we were at the beginning of our coding journey, I would tell you to simply copy this prompt. But since we already have a pretty large code base at our hands, it will actually cause more harm than good initializing this prompt. Instead, let's go through the quick start manually and then utilize Liveblocks skills to help us enhance this setup which we are going to develop right now. Let's start by adding the necessary Liveblocks packages.
Once you've installed the packages, go ahead and initialize a new Liveblocks config file using the command listed below. Once you have the config generated, let's go ahead and configure it so it only holds the information which we are actually going to need. So we are not going to need pretty much any of these besides the user meta. So we can simplify this entire config so it looks like this. Our user meta object will have an ID and then an info object, which holds the user's name and an optional avatar.
And go ahead and save that file. Next step is to create a LiveBlocks room. Now, if you are in this documentation while you are logged in, it will actually load your project which you've created and it's automatically going to append the public API key here. Now if yours hasn't done that, don't worry, I'm going to show you where you can find your key. But for now, let's actually just create a room using this snippet.
So inside of your features workflows components create a new file called room.tsx and simply paste the content inside. So if you can't find this public key, you can go inside of your project here, API keys, and in here you have a public key. Now let's slightly modify this room component so that besides accepting children as the prop, it also accepts the room ID. And then we can remove the hard-coded ID and actually use the dynamic prop. The next step is to encapsulate our React flow component with that room we've just created.
But I would rather we encapsulate the entire workflow shell. So go inside of your app folder, Dashboard Workflows ID page.tsx and go ahead and encapsulate this inside of this new room component which we've just developed. So make sure you add the proper import Features Workflows Components Room and make sure that you pass the room ID matching the dynamic ID from the params. Step 5 is to set up a collaborative React flow diagram. In their documentation, they create a new component called Flow.
But in our example, we have a canvas. So what we actually need to do is we need to transform this canvas from using our use nodes state, use edges state on connect and actually make it use use live blocks flow hook instead. Let's go ahead and create a prompt that says the following. Transform the canvas component hooks to live blocks hooks. Do not modify edges or nodes.
Only change the API which is used. Desired result and then we can just copy this part of their example so it understands that this is the only thing we are interested in and let's go ahead and simply append live blocks best practices and let's execute. Let's take a look at the changes. We removed use callback import because we no longer need it. We also removed unused imports from xyflow react.
We added use LiveBlocks flow from LiveBlocks React flow and we also added LiveBlocks React flow styles.css I assume this was added because we appended LiveBlocks best practices if your agent didn't add that go ahead and add it I mean it's a step anyway and about the changes here so it completely removed use nodes state, use edges state and on connect and it replaced it with a very clean use live blocks flow And then from here with the structure, the nodes, edges, onNodesChange, onEdgesChange, onConnect and onDelete. And the actual configuration for nodes and edges in this hook stayed the same. So we reused our initial nodes and our initial edges. That's also important. Make sure this wasn't modified.
And the only change in the React flow component is the wiring of the onDelete prop which was unused before. Brilliant. So the component should now look like this. Pretty similar to what it was before but actually a bit simplified now because we get all of our API from a single hook. In step six, we have to render the cursors component from LiveBlocks React Flow, as well as add some additional styles.
So let's go ahead and do that. First things first, make sure you import cursors from Liveblocks React Flow, then make sure that you have all three styles. So XYFlow style, Liveblocks React UI style and Liveblocks React Flow styles. So you can just verify that you have all three here. And then inside of the React flow, beneath or above the controls, simply render the cursors component.
You can now open another Chrome browser, log in with a different user, And invite yourself to the same organization. So you can see I have two different users but both of them are in the same organization. And both of them have opened the exact same workflow and now their cursors are visible. Not only are their cursors visible but all changes they do are visible. Obviously, it goes on both sides.
And yes, there is a way to improve this throttle here. So what you want to do is you want to go inside of the room component, find the LiveBlocks provider and go ahead and add throttle and set it to 16 and save. And then go ahead and refresh your pages and then you will see a much smoother experience if you want to demo it to someone. This is a pretty good spot for a checkpoint So let's go through our files and let's commit our changes. So first of all you should have LiveBlocks config file which has a very simple user meta object inside.
You should have a package.json modification with all the relevant LiveBlocks packages. You should have a page modification which renders the room component, passes the room ID prop and encapsulates the workflow shell, thus providing the live block API inside of our canvas component. Speaking of canvas component, you should have this modification inside where we technically replace the entire local state and replace it with live blocks and we also add floating cursors around so we can see who is in the room with us. And in the actual room you should have the exact snippet which we copied from the documentation. Now since we're using the public API key it isn't really terrible if this leaks but let's not give anyone the opportunity anyway to use your usage or anything like that.
So let's replace this with an environment key. So it's very important that you prefix your environment key with next underscore public because this will be injected in a component. And inside of Next.js the only environment keys which can be injected like that are those with a prefix of NextPublic. So go ahead and name this NextPublicLiveBlocksPublicKey and then the value and then inside of here let's do process.environment NextPublicLiveBlocksPublicKey And to get rid of the error, add an exclamation point. Don't worry, we're not gonna continue using this public API key.
We are later going to implement proper live blocks authentication and organization scoping. So only certain users from organizations can access rooms and not whoever has the URL. So go ahead and git add, git commit and git push. Remember to add the new environment variable to your railway service so that the deployment actually works if you want to test it out or share it with your friends. So click on the raw editor and after trigger secret go ahead and add next public live blocks public key, update variables and click deploy.