Before we develop the UI which will allow us to add new nodes into the canvas, drag them around and connect them, it's important to understand how we're going to develop the execution logic of these workflows. This is an example workflow which we are going to be able to build once we implement the UI. So take a look at this process right here. It starts with opening a URL. Then it goes to the agent node which is instructed to configure a Porsche 911.
After that we connect it to extract node whose job is to extract the relevant information and that is connected to a send email node whose job is to send an email. These types of workflows cannot function within your normal HTTP request. Every classic request has some kind of timeout. Regardless of if you're deploying on railway, Vercel or your custom VPS, you will be hit with some kind of HTTP timeout error, which is not something we want when developing these long-running workflows. What we need is something built for AI workflows and long-running tasks with queues, retries, and elastic scaling.
And Trigger.dev is the perfect solution for what we need. Even on their landing page, you can find a use case for browser automation using Browserbase, which is exactly the way we are going to implement our functionality. Besides that, Trigger comes built in with everything you see here on the screen. And if you are still not convinced or you are unsure about using a third-party library, rest assured because Trigger.dev is open source and self-hostable. You can use the link on the screen to get on their page and create an account.
Once you create your account, go ahead and create a new project. Once you set up a new project, you will see the installation wizard. This is a manual installation wizard, which is perfectly fine to use, but since we are using agentic coding, they actually have a prompt that we can use. So let's go onto their landing page, documentation, and find the quick start. In here you will find setup with AI.
Now Trigger's quick start is intended to be used a little bit differently in comparison to Clerks or Neons, which we had used before. So what I would recommend is having cloud code or whatever is your coding agent opened on one side and on the other side or just in a new window have your regular terminal open. Let's go ahead and copy their prompt and paste it into cloud code. Depending on the agent you're using you might get a little bit of a different response but in general it should be something like this it should give you a very quick summary of your current code base and then it should tell you that you need to check whether you have a trigger.dev account So you have to manually tell it, yes, I have a trigger.dev account. And this is what's going to happen next.
It's going to try to run trigger.dev latest init, but for example, my Cloud code immediately noticed that init is an interactive command, meaning that it's going to prompt the user for an organization and project selection or if you're not authenticated it's going to log in via browser. So it knows that it won't be able to run this itself. That's why I told you to prepare a normal terminal on the side. What I would recommend answering now is the following. Yes, I have a trigger.dev account.
I will run the setup manually and tell you once it's done. So you can review the code changes and proceed with the trigger.dev setup. So there's no point in telling it can you go ahead and run this command. You can see that mine has already detected that that would fail because it will. So let's go ahead and actually run this ourselves.
The first thing that's going to happen is that we are going to have to authenticate our account. Next, it's going to list our projects, so just go ahead and select whichever project you have just created. Now it's going to install the dependencies in our code base. After trigger dependencies have been installed, it's going to ask you where you want to create the trigger directory. And the placeholder is source trigger.
Since we are not using the source folder, as you can see, We only have the root directly here. Let's go ahead and make sure that it doesn't create one unnecessarily and just put the name trigger inside instead. Now it's asking you to choose an example to create in that directory. If you really want to play around and explore, you can choose the scheduled task, but I'm going to choose the simple option which is just a hello world. Before we proceed forward, I want to focus on the files it has modified or created.
So first in the package JSON, we now have trigger.dev.sdk. This is the version I am on. And we also have trigger.dev.build in the dev dependencies. We have a new file trigger.config.ts which is basically connected to the project we have selected, as well as some max duration and retry options here, and the directory from which it's going to read long-running tasks or durable functions which we are going to define. And then we have some updates to the TS config and we have an example file inside of the trigger folder right here.
Now here's one interesting thing. So the CLI which I used has generated this code and I can see this import here, trigger.devsdkv3. But if you actually take a look at their quick start and if you look at critical rules, you will see The rule always import from trigger.devsdk, never import from SDK version 3. So that is why it's useful to use this setup with AI, even though we had to manually do a few things. So what I would recommend doing now is the following.
Manual setup complete, review the files and follow the critical rules from the initial instructions. And let's see what it's going to do. Let's take a look at what happened. So it reviewed the generated files, it detected that the init worked but both files generated and violated the critical rule. They import from version 3.
So it fixed that and it just uses the SDK instead. So both of my files example.ts and trigger.config now have the proper import. As you can see there are no errors meaning that that truly does work. So if I take a look at trigger, there we go. No need for version three because it's redundant at this point.
So let's go ahead and see what it recommends doing next. Now that we have this trigger config set up, let's go ahead and actually run the dev server. So this is the command that it gave me and it also recommends running this in its own tab because it's a long running task. So let's go ahead and do npxtrigger.dev latest dev within our project right here and that is going to build a local worker. And now if you actually go back here you should no longer see the installation wizard, you should instead see the very file which we developed, I mean the command line interface developed here, visible right here.
Pretty cool. So I'm going to go ahead and respond with the following. Development server is running and the dashboard is no longer displaying the installation wizard. Instead it's showing the registered task. Now let's follow the step 4 which it has generated for me.
Obviously if yours tells you to do something different, you can follow that instructions but you can just follow what I do because it's the same thing, right? So I'm going to copy this payload which it has prepared for me which is a super simple object with key message and value of hello from the dashboard. But before I do that I just want to manually review this code right here. So this is a hello world task, which uses the task API from trigger. Its ID is hello world.
Its max duration is 300. And its run function does the following. It's an asynchronous function, which accepts a payload. It currently has a type error here. We can just turn it off or just change this to unknown if it bothers you.
And then immediately once the task is run, it's going to log hello world and it's going to display the payload. And then it's going to wait for 5 seconds once again using trigger API and at last it's going to return the output. So what I would actually recommend is changing this to task finished so it doesn't confuse you with the log here and save this file. And now let's go ahead and actually run the test here. So go ahead and find your workflow here and click on test.
Now in the payload here, let's go ahead and do that. Message hello from the dashboard and down at the bottom you can find run test. So let's see what happens. First we have the payload visible here. Hello from the dashboard.
Then immediately we have a log. Hello world. And then no output yet. It's not until five seconds pass and only then do we get the output task finished. We have successfully developed our first long-running task, which will be the base behind the entire workflow execution logic.
This is of course a super simple example, but I think you can already see how useful this will be when we have actual long-running tasks and AI workflows with topologically sorted nodes which pass data through one another. And besides the dashboard, you will also see the output of the finished task in your terminal. Since the agent tells me that there are step 5 and step 6 we have to do, I'm just going to respond run completed successfully to see what is the next step I have to do. So the next step is to establish a trigger secret key in our dot environment. So what the agent already did for me is it actually modified my dot environment dot example.
You probably don't have this and you don't need it yet. I'm maintaining this for this repository when it becomes a tutorial repository, right? So whoever clones the repository has an environment example. But what you should be looking at is the .environment.local file. And inside I'm just going to go ahead and prepare the following.
So don't be confused, okay? So far you should have the database, neon, clerk and these okay. You don't need to maintain environment dot example. I am maintaining that so it's easier for me to develop this tutorial. So now let's go ahead and follow its instruction on how to obtain the trigger secret key.
So in the dashboard make sure you are in the dev environment. So let's ensure we are. Dev environment. Then Let's go inside of the API keys. So let's see, how can we find that?
There we go, API keys. And in here we have a secret key. So I'm just gonna go ahead and copy this and then I'm going to paste it here. There we go. Just like that, we added our trigger secret key.
So let's see what do we have to do next. It added the documented placeholder. So yours probably didn't do that if you don't have a .environment.example. And then we have step six, triggering from your Next.js backend. You are on Next.js 16, so you'll trigger the task from a server action or a route handler.
The key rule is a type only import of the task, so it's code and never gets bundled into your app. So in here It's recommending something like a server action, which imports the Hello World task and then executes it with a payload hello from my app. Okay, so here's what I'm going to tell it to do now. Before we do this, maybe yours already did that, you know, it's perfectly fine, but here's what I wanna do first. Is there any Trigger AI tooling you can recommend for me to install.
So before we proceed with building execution from our Next.js app. So what it did is it fetched the documentation from trigger.dev. So in case yours didn't do that or it maybe used its training data, I want to show you that you can go inside of Trigger documentation, you can scroll down and you can find Building with AI. So my agent tells me that I already have an MCP server, which is okay. MCP server basically allows the connection between Cloud Code and Trigger in a way that I can tell Cloud Code create a new project in my workspace or create a new organization, right?
Things like that. But skills will be more useful for us because that will allow us to properly, programmatically use Trigger. So because of that, I would recommend that we first focus on installing trigger skills. So let's go ahead and go inside of our terminal here. We can close the dev running task and let's run the following command.
So the skills installer is asking me which targets I want to support. So I'm going to select Cloud Code. If you're using something like OpenCode or Codex, you would select agents.md. Agents.md is also going to cover like 99% of others. So let me go ahead and select these two.
Now let's choose the skills we want to install. So in here we have trigger authoring chat agent, then we have trigger authoring tasks, then we have chat agent advanced, cost saving, getting started, and real time and frontend. So I'm gonna select all of them and I'm going to press enter and now it's going to install those. You're gonna have to do the same selection for the other option, agents MD and yes, this is a bit weird. It seems broken.
It actually happens in almost every CLI tool that I use. Maybe it's ghosty, maybe it's my shell, but whenever I'm too zoomed in, everything seems mushed. But yeah, I just basically select everything. If for whatever reason you had trouble running their executor you can most certainly find on skills.sh trigger right here trigger.dev let's see So we have Trigger Setup, Trigger Real-Time. I would recommend having the Setup, the Real-Time, Tasks, Conf, all of these to be honest.
Yeah, Just make sure that they are coming from trigger.dev. Okay, as long as that is the author, you can go ahead and install all of those and you will have pretty much the same thing as me. So, okay, at this point, I have a lot of skills here. Let me do a quick review here. So I'm going to look at my cloud.
Let's see skills. These are the ones that I have. Okay, trigger, authoring chat agent, authoring tasks, chat agent advanced, cost savings, getting started real time and front end. So if you are adding yours individually here, I would recommend trying to find the real-time and frontend. Let me see trigger real-time looks like they have real-time.
Is there maybe frontend? Maybe they've bundled that into one. Anyway, just use npxtrigger.dev latest skills and then you will be able to find these ones that I have selected. If this is happening to you, like your shell looks weird, try zooming out, making the text smaller. I think that can fix it sometimes.
But yeah, basically just use your arrow keys and press space to select all of them. Or maybe their skills agent, skills CLI has the ability to like select all of them. Yeah, non-interactive install. You can just use this and then that's just going to install every skill without prompting. Perfect.
So yeah, here's the solution if you are having trouble. Beautiful. So now that we have all of those skills, let me just go a little bit back here to see if there's anything useful that I can have here. Skills and MCP server. Apparently we already have the MCP server so we don't need that.
LLMs.txt. This is when you don't use skills and just wanna point your agent to a web search temporarily so it gets the context. Okay, I think I am satisfied with this at this point. Let me just do, looks like there was a change in agents.md. So in here it added trigger.dev agent skills and it basically instructs, it injects, sorry, so agents.md is injected into every single prompt that we do, agents.md or CloudMD.
And now it added this here, which basically makes sure that whenever an agent needs to use a skill, it's going to use a skill. Okay, basically instructions on how to load the most relevant skills. Now, It's not the end of the world if yours look different, right? But this will just make it easier for agents to understand how to build tasks. And that's the whole point of agentic coding, right?
Of providing a few examples yourself and then letting the AI do 50 other examples so you don't have to do it, right? Or in this case, the authors are providing us with examples. Since you already have 20 uncommitted changes, I think this is a pretty good checkpoint. So I'm going to do git commit and then git push. Now let's quickly create the UI for this run button so that we can test our new trigger skills and see if we can make an agent connect a task with being executed by clicking on the run button.
So let's go ahead and modify our workflow shell component. So workflow shell currently has all the panels which we need and I want to put the run button inside of the inspector panel right here. So I'm going to highlight this part right here which will make the three lines selected. If you can't do that then just go ahead and tag the workflow shell in your editor like this. Make sure you don't tag the specification, tag the component.
So I'm going to tell you the following, separate the selected lines. If you can't select lines, then tell it separate the inspector div, right? Separate inspector div in its own component called right sidebar.tsx and instead of a sidebar.tsx and instead of a centered inspector paragraph, render a button component with a play icon and Run text. Great. So now my right sidebar and is its own component and I can click here and I have a button with a play icon inside.
So if I go ahead and run my app and if I visit localhost 3000 here and select the workflow. I should see a big run button here. So before we develop a prompt, which is going to connect or wire up the right sidebar button to executing a trigger.dev task, it's a good idea to check whether the skills are actually loaded in your agent. So try and search for something like trigger. And if it's not here, go ahead and try doing reload skills.
And if that doesn't work, go ahead and reload the entire window. So then if I go ahead and search for trigger, there we go. A bunch of skills available. And now we can execute a prompt like this. Use trigger.dev skills to create a new server action in our workflows actions file.
Call that server action run workflow action, which will trigger a example task which we got when we set up trigger. Then wire up that server action to the right sidebar button. Let's go ahead and execute this. Let's take a look at the result. So first things first, in our features workflow actions we now have the following.
We now have tasks imported from trigger dev SDK and we have a type hello world task imported from trigger example. And then down here we have a new function run workflow action which once again validates the organization ID. It doesn't have to do that yet because we are not really fetching anything with this org ID but why not. And then what it does is it very simply executes the, or should I say triggers the task called hello world. The only thing it didn't do is it didn't add any payload.
So perhaps we can add some payload. Let me close this here. So I'm gonna go ahead and do something like message and I will do hello from right sidebar. So we know it's executed from there, right? And this run workflow action was, I suppose, connected through the right sidebar.
There we go, use client. And in here we have run workflow action imported. We have is pending, start transition, on run, all added to the button. And let me look at the change in the workflow shell so okay in here we just have the right sidebar rendered nothing more nothing less so now let me go ahead inside of here and let me do the following I want to prepare my tasks here or my runs. I think that might be a better idea here.
First of all my local server is not connected to trigger.dev so it's pretty good reminder that I need to both have trigger.dev latest dev running and npm run dev. So make sure that you have both as well. And that should make this connected. So let's just refresh. Perfect.
And now let's go ahead and click run here. And let's go ahead and refresh this and there we go. We can now successfully execute long running tasks and AI workflows from our Next.js application. And now just for fun I'm going to do the following. I'm going to say use and then I can use the slash command and find trigger real-time and front-end skill to display the feedback of the task I'm not really sure what to expect here.
I think every agent will develop something different. I just want to see if the skill actually works and if it can produce some useful results here. So it looks like this is a pretty useful thing to run because it's going to install a package, TriggerDevReactHooks. So if you haven't, go ahead and just run a simple prompt with this skill. It will most likely do the same.
If it doesn't, you can always instruct it to use this dependency specifically and then it's going to do that. And let's take a look at the changes it actually produced here. So first I'm taking a look at the actions just to see if anything has changed here. So nothing seems to be changed here. Now let's look at the package.json and this is where we see the first change.
Trigger.dev react-hooks 4.5.1 has been added to my dependencies. And let me take a look at the right sidebar here. So what do we have here? There we go. So we have a new function called run status which uses the use real-time run and it uses the access token handle public access token so I'm assuming it read the skill and it knows how to set this up.
Chances are yours has developed something different right But as long as it's anything similar to this, if you can see hooks like use real-time run, and you can see the public access token being added here, it doesn't really matter how it implemented this because obviously we're going to modify this later, We're going to delete the whole file. I just want to make sure that, you know, we can play around and you feel comfortable playing around with the Gentic coding, right? It doesn't need to be the same as mine. So now, in theory, we should be able to click Run and we should be getting some more useful information. Starting run, dequeued, let's see if anything's going to update.
So what does this mean? What just happened? I'm not even sure. Oh, it completed. Let me try again.
Run, dequeued, executing, and then we should get completed after. There we go. So we now have real time information here. Yours can have slightly different UI that's perfectly fine but I think you now get the idea that this real time feedback is going to be important for us because if you take a look at our Canvas design here these nodes will need to be executed one by one, right? So we are eventually going to have something like a node in progress and that's gonna look like this.
So how do we make sure that whichever node is currently executing is the one that's currently highlighted well exactly with a skill like trigger real-time and frontend. So that's why I wanted you to run this prompt, not so you have the exact code as me, but so that you at least have the React hooks package installed. Right? Regardless of how your agent got to this solution, it really doesn't matter because we are later going to rework this and make it look like it's supposed to look like by first cleaning this entire component and then starting from scratch. So don't worry at all.
As long as you can actually see some real-time feedback, it should all be perfectly fine. Before we commit and push these changes, remember that we added a new variable to environment.local, so go ahead and simply add a new variable here or just use the raw editor like this and then add it at the end. So trigger secret key and click update variables like that. And if you want to, you can click deploy. And now let's go ahead and commit.
That brings us to the end of this chapter. Amazing job. And see you in the next one. If you get an error like this on your railway redeployment, it appears to once again be some kind of conflict in the package lock file. The fix is very easy, you just have to remove node modules and package lock, run an npm install and then go ahead and commit that new package lock which will eventually cause the redeployment to work but I'm going to go ahead and research in the meantime why this is happening.
Perhaps this is only happening to me but I'm recording just in case any of you has this problem as well. So from now on remember if you see npmci and if you see mentions of package lock or something like this remember that you just have to reinitialize the package lock file.