Skip to main content

Prerequisites

Initial setup

1

Run the CLI init command

In the root of your Remix project, run:
npx trigger.dev@latest init
This creates trigger.config.ts and a sample task at src/trigger/example.ts.
2

Start the dev server

Run the Trigger.dev dev server (keep your Remix dev server running in a separate terminal):
npx trigger.dev@latest dev
3

Run a test

Open the Trigger.dev dashboard, navigate to your project, and use the Test page to trigger the hello-world task.
4

View your run

Click through to the run page to see live logs and the task output.

Set your secret key locally

Add your TRIGGER_SECRET_KEY to the .env file in the root of your Remix project. Get your DEV secret key from the API Keys page in the dashboard: Find your DEV API key under API Keys in the Trigger.dev dashboard.

Triggering tasks from Remix

1

Create an API route

Create app/routes/api.hello-world.ts:
app/routes/api.hello-world.ts
import type { helloWorldTask } from "../../src/trigger/example";
import { tasks } from "@trigger.dev/sdk";

export async function loader() {
  const handle = await tasks.trigger<typeof helloWorldTask>("hello-world", "James");

  return new Response(JSON.stringify(handle), {
    headers: { "Content-Type": "application/json" },
  });
}
2

Test your route

With both the Remix dev server and the Trigger.dev dev server running, visit http://localhost:5173/api/hello-world. The task will be triggered and the run handle returned as JSON.

Add environment variables

Add any environment variables your tasks require to the Trigger.dev dashboard under Environment Variables before deploying.

Deploying your task

npx trigger.dev@latest deploy

Deploying to Vercel Edge Functions

The @trigger.dev/sdk package supports the edge runtime out of the box. Use a type-only import for the task to ensure compatibility.
1

Update your API route for edge

app/routes/api.hello-world.ts
import { tasks } from "@trigger.dev/sdk";
import type { helloWorldTask } from "../../src/trigger/example";
//      πŸ‘† type-only import

export const config = {
  runtime: "edge",
};

export async function action({ request }: { request: Request }) {
  const payload = await request.json();
  const handle = await tasks.trigger<typeof helloWorldTask>("hello-world", payload);
  return new Response(JSON.stringify(handle), {
    headers: { "Content-Type": "application/json" },
  });
}
2

Create or update vercel.json

vercel.json
{
  "buildCommand": "npm run vercel-build",
  "devCommand": "npm run dev",
  "framework": "remix",
  "installCommand": "npm install",
  "outputDirectory": "build/client"
}
3

Update package.json scripts

Add the vercel-build script which copies static assets to the expected output path:
package.json
{
  "scripts": {
    "build": "remix vite:build",
    "dev": "remix vite:dev",
    "start": "remix-serve ./build/server/index.js",
    "typecheck": "tsc",
    "vercel-build": "remix vite:build && cp -r ./public ./build/client"
  }
}
4

Deploy to Vercel

Push your code to a Git repository, then create a new project in the Vercel dashboard and connect it to your repo.
5

Add your secret key to Vercel

In your Vercel project settings, add the environment variable:
TRIGGER_SECRET_KEY=your-secret-key
Get your production secret key from the API Keys page in the Trigger.dev dashboard.
6

Test in production

After deploying, send a POST request to verify the task triggers correctly:
curl -X POST https://your-app.vercel.app/api/hello-world \
  -H "Content-Type: application/json" \
  -d '{"name": "James"}'
The runtime: "edge" configuration improves cold-start times on Vercel’s Edge Network. The type-only import (import type) ensures the task code itself is never bundled into the edge function β€” only the type information is used at compile time.

Additional resources

Build extensions

Add Python, browsers, FFmpeg, and other system dependencies to your tasks

Deployment guide

Learn how to deploy your tasks to production

Build docs developers (and LLMs) love