> ## Documentation Index
> Fetch the complete documentation index at: https://trigger.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Preview branches

> Create isolated environments for each branch of your code, allowing you to test changes before merging to production. You can create preview branches manually or automatically from your git branches.

## How to use preview branches

The preview environment is special – you create branches from it. The branches you create live under the preview environment and have all the features you're used to from other environments (like staging or production). That means you can trigger runs, have schedules, test them, use Realtime, etc.

![Preview environment and branches](https://mintcdn.com/trigger/uys6iMwf9B_ojh8r/deployment/preview-environment-branches.png?fit=max\&auto=format\&n=uys6iMwf9B_ojh8r\&q=85\&s=1ea48ad7377b6824a293e69044448b53)

We recommend you automatically create a preview branch for each git branch when a Pull Request is opened and then archive it automatically when the PR is merged/closed.

The process to use preview branches looks like this:

1. Create a preview branch
2. Deploy to the preview branch (1+ times)
3. Create a named **Trigger only** API key in the Preview environment, then trigger runs using the key (`TRIGGER_SECRET_KEY`) and branch name (`TRIGGER_PREVIEW_BRANCH`).
4. Archive the preview branch when the branch is done.

There are three main ways to do this:

1. Automatically: using the [GitHub integration](https://trigger.dev/docs/github-integration.md), which deploys pull requests to preview branches and archives them when the PR is merged or closed, without a GitHub Action.
2. Automatically: using GitHub Actions, if you deploy from your own CI workflows.
3. Manually: in the dashboard and/or using the CLI.

Pick one of the automatic options, not both.

### Limits on active preview branches

We restrict the number of active preview branches (per project). You can archive a preview branch at any time (automatically or manually) to unlock another slot – or you can upgrade your plan.

Once archived you can still view the dashboard for the branch but you can't trigger or execute runs (or other write operations).

This limit exists because each branch has an independent concurrency limit. For the Cloud product these are the limits:

| Plan | Active preview branches |
| - | - |
| Free | 0 |
| Hobby | 5 |
| Pro | 20 (then paid for more) |

For full details see our [pricing page](https://trigger.dev/pricing).

## Triggering runs and using the SDK

Create a named API key in the Preview environment and set it as `TRIGGER_SECRET_KEY`. Set `TRIGGER_PREVIEW_BRANCH` to select the branch that receives the runs.

When deploying to somewhere that supports `process.env` (like Node.js runtimes) you can just set the environment variables:

```bash theme={"theme":"css-variables"}
TRIGGER_SECRET_KEY="tr_preview_sk_1234567890"
TRIGGER_PREVIEW_BRANCH="your-branch-name"
```

If you're deploying somewhere that doesn't support `process.env` (like some edge runtimes) you can manually configure the SDK:

```ts theme={"theme":"css-variables"}
import { configure } from "@trigger.dev/sdk";
import { myTask } from "./trigger/myTasks";

configure({
  secretKey: "tr_preview_sk_1234567890", // WARNING: Never actually hardcode your secret key like this
  previewBranch: "your-branch-name",
});

async function triggerTask() {
  await myTask.trigger({ userId: "1234" }); // Trigger a run in your-branch-name
}
```

### Triggering across multiple branches from one process

If a single process needs to trigger runs in several preview branches (or a mix of prod and preview), use `new TriggerClient({...})` for each target instead of mutating global config. Each instance owns its own auth and branch.

```ts theme={"theme":"css-variables"}
import { TriggerClient } from "@trigger.dev/sdk";

const signupFlow = new TriggerClient({
  accessToken: process.env.TRIGGER_PREVIEW_KEY,
  previewBranch: "signup-flow",
});
const checkout = new TriggerClient({
  accessToken: process.env.TRIGGER_PREVIEW_KEY,
  previewBranch: "checkout-redesign",
});

const payload = { to: "user@example.com" };
await Promise.all([
  signupFlow.tasks.trigger("send-email", payload),
  checkout.tasks.trigger("send-email", payload),
]);
```

See [Multiple SDK clients](https://trigger.dev/docs/management/multiple-clients.md) for the full pattern.

## Preview branches with GitHub Actions (recommended)

This GitHub Action will:

1. Automatically create a preview branch for your Pull Request (if the branch doesn't already exist).
2. Deploy the preview branch.
3. Archive the preview branch when the Pull Request is merged/closed. This only works if your workflow runs on **closed** PRs (`types: [opened, synchronize, reopened, closed]`). If you omit `closed`, branches won't be archived automatically.

```yml .github/workflows/trigger-preview-branches.yml theme={"theme":"css-variables"}
name: Deploy to Trigger.dev (preview branches)

on:
  pull_request:
    types: [opened, synchronize, reopened, closed]

jobs:
  deploy-preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js 20.x
        uses: actions/setup-node@v4
        with:
          node-version: "20.x"

      - name: Install dependencies
        run: npm install

      - name: Deploy preview branch
        run: npx trigger.dev@latest deploy --env preview
        env:
          TRIGGER_ACCESS_TOKEN: ${{ secrets.TRIGGER_PREVIEW_ACCESS_TOKEN }}
```

For this workflow to work, you need to set the following secrets in your GitHub repository:

* `TRIGGER_PREVIEW_ACCESS_TOKEN`: A Trigger.dev API key for the Preview environment with **Deploy only** access. [Create a deployment API key and add it to GitHub](https://trigger.dev/docs/github-actions.md#create-a-deployment-api-key).

Notice that the deploy command has `--env preview` at the end. We automatically detect the preview branch from the GitHub actions env var.

You can manually specify the branch using `--branch <branch-name>` in the deploy command, but this isn't required.

## Preview branches with the CLI (manual)

### Deploying a preview branch

Creating and deploying a preview branch manually is easy:

```bash theme={"theme":"css-variables"}
npx trigger.dev@latest deploy --env preview
```

This will create and deploy a preview branch, automatically detecting the git branch. When your CI checks out a detached HEAD, the branch is read from the CI provider's branch variable instead (GitLab, Bitbucket, CircleCI, Buildkite, Travis CI, Jenkins and Azure Pipelines are supported). If for some reason the auto-detection doesn't work it will let you know and tell you do this:

```bash theme={"theme":"css-variables"}
npx trigger.dev@latest deploy --env preview --branch your-branch-name
```

### Archiving a preview branch

You can manually archive a preview branch with the CLI:

```bash theme={"theme":"css-variables"}
npx trigger.dev@latest preview archive
```

Again we will try auto-detect the current branch. But you can specify the branch name with `--branch <branch-name>`.

## Creating and archiving preview branches from the dashboard

From the "Preview branches" page you can create a branch:

![Preview branches page](https://mintcdn.com/trigger/uys6iMwf9B_ojh8r/deployment/preview-branches.png?fit=max\&auto=format\&n=uys6iMwf9B_ojh8r\&q=85\&s=2f169fe8a12fd5e71c68e72dff38d0ba)

![Create preview branch](https://mintcdn.com/trigger/uys6iMwf9B_ojh8r/deployment/preview-branches-new.png?fit=max\&auto=format\&n=uys6iMwf9B_ojh8r\&q=85\&s=daac2d1f55ba7ddc7bba83bceb9f65f8)

You can also archive a branch:

![Archive preview branch](https://mintcdn.com/trigger/uys6iMwf9B_ojh8r/deployment/preview-branches-archive.png?fit=max\&auto=format\&n=uys6iMwf9B_ojh8r\&q=85\&s=1908c37fe8b46c3f942b0caf386094fd)

## Environment variables

You can set environment variables for "Preview" and they will get applied to all branches (existing and new). You can also set environment variables for a specific branch. If they are set for both then the branch-specific variables will take precedence.

![Environment variables](https://mintcdn.com/trigger/uys6iMwf9B_ojh8r/deployment/preview-environment-variables.png?fit=max\&auto=format\&n=uys6iMwf9B_ojh8r\&q=85\&s=dcf6d3db8d2892e68351ddcdd367ac6e)

These can be set manually in the dashboard, or automatically at deploy time using the [syncEnvVars()](https://trigger.dev/docs/config/extensions/syncEnvVars.md) or [syncVercelEnvVars()](https://trigger.dev/docs/config/extensions/syncEnvVars.md#syncvercelenvvars) build extensions.

### Sync environment variables

Full instructions are in the [syncEnvVars()](https://trigger.dev/docs/config/extensions/syncEnvVars.md) documentation.

```ts trigger.config.ts theme={"theme":"css-variables"}
import { defineConfig } from "@trigger.dev/sdk";
// You will need to install the @trigger.dev/build package
import { syncEnvVars } from "@trigger.dev/build/extensions/core";

export default defineConfig({
  //... other config
  build: {
    // This will automatically detect and sync environment variables
    extensions: [
      syncEnvVars(async (ctx) => {
        // You can fetch env variables from a 3rd party service like Infisical, Hashicorp Vault, etc.
        // The ctx.branch will be set if it's a preview deployment.
        return await fetchEnvVars(ctx.environment, ctx.branch);
      }),
    ],
  },
});
```

### Sync Vercel environment variables

You need to set the `VERCEL_ACCESS_TOKEN`, `VERCEL_PROJECT_ID` and `VERCEL_TEAM_ID` environment variables. You can find these in the Vercel dashboard. Full instructions are in the [syncVercelEnvVars()](https://trigger.dev/docs/config/extensions/syncEnvVars.md#syncvercelenvvars) documentation.

The extension will automatically detect a preview branch deploy from Vercel and sync the appropriate environment variables.

```ts trigger.config.ts theme={"theme":"css-variables"}
import { defineConfig } from "@trigger.dev/sdk";
// You will need to install the @trigger.dev/build package
import { syncVercelEnvVars } from "@trigger.dev/build/extensions/core";

export default defineConfig({
  //... other config
  build: {
    // This will automatically detect and sync environment variables
    extensions: [syncVercelEnvVars()],
  },
});
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.