{ Simple Frontend }

How to deploy safely with Vercel

Learn how to run end-to-end tests for your pull requests previews and before you deploy your main branch to production with Vercel.

Jeremy Colin Jeremy Colin
May 3, 2025 - 5 min read

Vercel and Github configuration

After you have created your Vercel project from your Github repository, there are a few small steps to take:

  1. In the project Settings > Environments > Production, disable Auto-assign Custom Production Domains. This is important otherwise every pull requests merged into your main branch will trigger an update to your production site.
Disable auto-assign custom production domains in Vercel project settings
  1. In the project Settings > Deployment Protection > Protection Bypass for Automation, click “Add Secret” to generate a new environment variable called VERCEL_AUTOMATION_BYPASS_SECRET. Paste this value in your Github actions repository secrets with the same name: VERCEL_AUTOMATION_BYPASS_SECRET. This is important so that Vercel lets you run the end-to-end tests on the protected preview environment.
Protection bypass for automation in Vercel project settings
  1. In Account Settings > Tokens, create a new token for the organization your project belongs to. This will be used by Github Actions to deploy your application to production. Paste this value in your Github repository actions secrets with the name: VERCEL_TOKEN.

  2. While you are inside the Github repository secrets, add one more secret with the name: VERCEL_TEAM_SCOPE which is the slug of the organization your project belongs to as in vercel.com/your-organization-slug/

Run end-to-end tests for your pull requests integration

I recommend to use Playwright as end-to-end tests solution as it is reliable and efficient. Vercel already deploys your pull requests branches to a preview environment, so we can easily setup a github action to run our end-to-end tests after the deployments as shown below:

Vercel Excalidraw diagram describing the deployment process for pull requests

Here I will assume you already have a Playwright test suite or equivalent that you want to run. If not, you can follow this guide to setup one. What is important here is that you can configure a dynamic BASE_URL environment variable to indicate where the tests should run.

Now all you need is a github action workflow that will run your end-to-end tests after the deployment to the preview environment, here is an example below using pnpm:

name: End to End Tests
on:
deployment_status:
jobs:
e2e:
if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' && github.event.deployment.environment == 'Preview'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.deployment.sha }}
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps chromium
- name: Run Playwright tests
run: pnpm run e2e
env:
BASE_URL: ${{ github.event.deployment_status.environment_url }}
VERCEL_AUTOMATION_BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }}

It is fairly straightforward: Vercel will build and deploy your pull request branch to a dedicated preview URL, and then the github action will run your end-to-end tests on it thanks to the BASE_URL environment variable which is set to the deployment_status URL.

You can also see that we are using the VERCEL_AUTOMATION_BYPASS_SECRET secret to bypass the deployment protection for automation as configured above.

That’s it! Now every pull request will run your end-to-end tests and report its status check in the Github UI.

You can also mark this status check as required in your github repository settings to ensure that your pull requests are not merged until the end-to-end tests pass.

Run end-to-end tests for your continuous deployment

While you are already well covered with end-to-end tests running before your pull requests are merged, you should also run those end-to-end tests on your main branch before going live. The reason is simple: your main branch is the real deal and I have seen too many incidents where things went wrong in production because the release deployed was never tested in its final state in a production-like environment.

If you disabled the Auto-assign Custom Production Domains in the Vercel project settings, you should now see your latest main branch commit as as Production: Staged deployment in the Vercel deployments UI:

Main branch staged deployment in Vercel deployments UI

To promote the depoyment, we will use a very similar recipe as the one we just setup for pull requests, except this time we will use the repository_dispatch event instead of deployment_status as recommended by Vercel:

Vercel Excalidraw diagram describing the deployment process for production after merges

Here is an example of a github action workflow that will run your end-to-end tests on your main branch before going live and then promote the deployment to production:

name: Deploy Production Vercel
on:
repository_dispatch:
types:
- "vercel.deployment.success"
jobs:
deploy-production-vercel:
if: github.event.client_payload.environment == 'production'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.client_payload.git.sha }}
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps chromium
- name: Run Playwright tests
run: pnpm run e2e
env:
BASE_URL: ${{ github.event.client_payload.url }}
PUBLIC_ENV: production
VERCEL_AUTOMATION_BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }}
# Promote deployment to production
- run: npx vercel promote ${{ github.event.client_payload.url }} --scope=${{ secrets.VERCEL_TEAM_SCOPE }} --token=${{ secrets.VERCEL_TOKEN }}

Now we have an extra step in our delivery pipeline to promote the preview deployment to production.

Also note the if: conditions we have in our workflows to ensure we are not running them on the wrong environments.

Now your deployments UI should look like this with the latest main branch commit marked as Production: Current deployment in the Vercel deployments UI:

Main branch current deployment in Vercel deployments UI

And that’s all there is to it! This is thanks to Vercel being well integrated with Github and already triggering all the events we need to run our end-to-end tests and promote our main branch deployment to production.

If it seems a little intimidating to setup, don’t worry, I have created an example repository that you can use as a starting point: Safe Continuous Deployments.