---
title: "Adding staging"
description: "Optional — add a pre-production context between `development` and production, with its own Workers, data and branch."
canonical_url: "https://nuxtstart.com/docs/getting-started/adding-staging"
---

Staging is optional. It's a pre-production copy of your project, with its own Workers, bucket,
content database, pool and Postgres, deployed from a `staging` branch so you can check a promotion
before it reaches production. Add it when you want that rehearsal, or skip this page and promote
`development` straight to `main`. Skipping costs nothing: only a push to a `staging` branch deploys
`staging`, so nothing reads its value files until one exists.

```mermaid
flowchart LR
    L["1. Local setup<br/>Both apps on your machine"] --> D["2. Deploying development<br/>A push deploys"]
    L --> R["3. Adding pull request previews<br/>Independent of development"]
    D --> S["**4. Adding staging**<br/>Optional"]
    S --> P["5. Going to production<br/>Your domain, real users"]
    D -. "without staging" .-> P
```

## Prerequisites

<table>
<thead>
  <tr>
    <th>
      You need
    </th>
    
    <th>
      How to get it
    </th>
    
    <th>
      Required
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <a href="/docs/getting-started/deploying-development">
        Deploying development
      </a>
      
       finished
    </td>
    
    <td>
      <code>
        development
      </code>
      
       deploying
    </td>
    
    <td>
      Yes
    </td>
  </tr>
  
  <tr>
    <td>
      A Postgres database for staging
    </td>
    
    <td>
      Any managed Postgres reachable from the internet, never one another context uses
    </td>
    
    <td>
      Yes
    </td>
  </tr>
  
  <tr>
    <td>
      Google, GitHub, and Polar credentials for staging
    </td>
    
    <td>
      <a href="/docs/configuration/provider-accounts">
        Set up sign-in and payments
      </a>
      
       — a separate client per context
    </td>
    
    <td>
      Only for the feature that reads them
    </td>
  </tr>
</tbody>
</table>

The repository needs no new secret or variable. The push identity already reads the `staging` tier,
and the Cloudflare token already creates every resource type staging binds.

## Add the context

### 1. Fill staging's Secret Tier

`staging` reads the `staging` environment at `/` in **apps/web's** Infisical project. Store the
connection string there:

```shell
infisical secrets set DATABASE_URL='<the staging connection string>' \
  --env=staging --path=/ --projectId='<apps/web project id>'
```

Then add staging's own value for every key that
[Set up your secret store](/docs/configuration/secret-store) put in `/local`. A feature you're
skipping takes a stand-in, as it does locally.

### 2. Write staging's values

Staging's origins take the same shape as development's, with its own context in them. Its client IDs
and contact address ship empty too:

```env [apps/web/.env.staging]
NUXT_PUBLIC_APP_BASE_URL=https://<slug>-web-staging.<subdomain>.workers.dev
NUXT_PUBLIC_APP_WEBSITE_BASE_URL=https://<slug>-site-staging.<subdomain>.workers.dev
GOOGLE_CLIENT_ID=<staging's Google client ID>
GITHUB_CLIENT_ID=<staging's GitHub client ID>
```

```env [apps/site/.env.staging]
NUXT_PUBLIC_APP_BASE_URL=https://<slug>-site-staging.<subdomain>.workers.dev
NUXT_PUBLIC_CONTACT_EMAIL=hello@example.com
```

Commit both on `development` and push.

### 3. Create the `staging` branch

From here promotion runs `development` → `staging` → `main`. Create the middle branch:

```shell
git checkout -b staging development
git push -u origin staging
```

That first push creates staging's Workers, bucket, content database and pool, each named
`<slug>-<app>-staging`, and deploys both applications. Every later push to `staging` deploys it
again. Nothing enforces the order — the gate reads only the branch pushed — so promote by merging
forward.

### 4. Onboard staging's sending domains

Staging sends from its own hostnames, `<slug>-<app>-staging.<zone>`. Onboard each one the way
[Email will not send until you onboard a domain](/docs/getting-started/deploying-development#email-will-not-send-until-you-onboard-a-domain)
walks it, reading the hostname with `APP_RUNTIME_CONTEXT=staging`.

A red run reads the same way it did for `development`:
[When it does not work](/docs/getting-started/deploying-development#when-it-does-not-work) lists the causes.

## Next steps

- [Going to production](/docs/getting-started/going-to-production) — the last stage, promoted
through `staging`, once the application and its name are final
- [Resources](/docs/deployment/resources) — what staging's first push created, and how to delete a
context's resources if you drop it later

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
