---
title: Migrate to Vercel from Netlify
description: Migrate your website's configuration from Netlify to Vercel
url: /kb/guide/migrate-to-vercel-from-netlify
canonical_url: "https://vercel.com/kb/guide/migrate-to-vercel-from-netlify"
published: 2025-11-03
last_updated: 2026-07-16
authors: Jason Hoch
related:
  - /docs/concepts/get-started/deploy
  - /docs/concepts/projects/custom-domains
  - /kb/guide/vercel-vs-netlify
  - /docs/deployments/environments
  - /docs/concepts/projects/project-configuration
  - /docs/routing-middleware
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---

In this guide, you will go through all the steps needed to migrate your Netlify application to Vercel.

## Project Creation

Before you can start the migration you need to create a project on Vercel. This [Getting Started](https://vercel.com/docs/concepts/get-started/deploy) guide will instruct you on how to add your project to Vercel.

Once the setup is complete, you can start migrating your application settings.

## Custom Domains

To migrate your domains to Vercel, refer to the following documentation:

- [Custom Domains](https://vercel.com/docs/concepts/projects/custom-domains)
  
- [Zero-Downtime Domain Migration with Vercel](https://vercel.com/guides/zero-downtime-migration-for-dns)
  

## Build Settings

Vercel will automatically detect the framework and any necessary build settings. However, you may have custom settings in [Netlify](https://vercel.com/kb/guide/vercel-vs-netlify) that you need to migrate. You need to find the settings which can be found in either the UI or your `netlify.toml` file.

### Gathering Netlify Build Data

#### 1\. Netlify UI Build Settings

Open your project in Netlify and find the `Site Settings`.

Select `Build and Deploy` from the left navigation. The `Build Settings` section includes the information Vercel needs to build and deploy your application.

The three fields that need to be copied to Vercel are:

- Base Directory
  
- Build Command
  
- Publish Directory
  

#### 2. `netlify.toml` File Build Settings

In your `netlify.toml` file, the build settings will be signified by a `[build]` table which lists all the currently configured options for each command.

Inside the `netlify.toml` file you can set a custom command to ignore builds signified by the `ignore` key.

```text
[build]
  base = "project/"
  publish = "build-output/"
  command = "echo 'default context'"
  ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF"
```

### Setup Build Settings on Vercel

Open your Vercel project and locate the `Settings` tab.

Locate the section called `Build and Development Settings` and fill in the Build Command and Output Directory sections.

There is a section below where you can enter the base directory if you are using a monorepo.

If you had an `ignore` key set in the `netlify.toml`, you can add that to your Vercel settings. Select `Git` from the left navigation in Vercel and locate the `Ignored Build Step` section where you can copy the command.

## Environment Variables

If you have environment variables configured in Netlify, those will need to be migrated to Vercel. These settings can be found in either the UI or your `netlify.toml` file.

### Gathering Netlify Environment Data

#### 1\. Netlify UI Environment Data

Open your project in Netlify and find the `Site Settings`.

Select `Build and Deploy` from the left navigation and locate the `Environment` section. This includes all the environment variables needed to configure your project, make note of them all to copy to Vercel.

#### 2. `netlify.toml` File Environment Data

In your `netlify.toml` file, each environment's variables are signified by a `[context.ENVIRONMENT.environment]` table which lists all the currently configured values for the environment.

```text
[context.staging.environment]
  NOT_PRIVATE_ITEM = "not so secret"
[context.prod.environment]
  NOT_PRIVATE_ITEM = "really not so secret"
```

### Setup Environment Variables on Vercel

Open your Vercel project and locate the Settings tab.

From the left navigation, select `Environment Variables` and paste your environment variables from Netlify. You can choose to configure them to only apply to any [specific environment](https://vercel.com/docs/deployments/environments) or any custom branch.

## Redirects and rewrites

There are two ways currently to configure rewrites and redirects in Netlify:

- A plain text file called
  

`_redirects`

 without a file extension to the publish directory of your site in Netlify

- One or more
  

`redirects`

 tables in your Netlify configuration file

`netlify.toml`

You will need to take note of all the redirects set up in Netlify to properly configure them in Vercel.

### Gathering Netlify Redirects Data

#### 1. `_redirects` File

In a `_redirects` file, each rule must be listed on a separate line, with the original path followed by the new path or URL. The status code is optional and listed at the end. A 200 status code indicates a rewrite.

```text
/home              /
/blog/my-post.php  /blog/my-post
/news              /blog
/cats              /dogs                  200
```

#### 2. `netlify.toml` File Redirects Data

In a `netlify.toml` file, each rule will be signified by a `[[redirects]]` table which lists all the currently configured options for each redirect.

```text
[[redirects]]
  from = "/old-path"
  to = "/new-path"
  status = 301

[[redirects]]
  from = "/search"
  to = "https://api.mysearch.com"
  status = 200
```

Once you have collected all the rewrites and redirects in your application you can start configuring them in Vercel. The method will depend on your application framework.

### Setup Redirects on Vercel

#### 1\. Next.js (`next.config.js`) Redirects

Next.js has a built-in way to configure redirects in your application and that is the preferred way to set them up in your application as they have precedence over platform-level redirects.

For each [redirect](https://nextjs.org/docs/api-reference/next.config.js/redirects) and [rewrite](https://nextjs.org/docs/api-reference/next.config.js/rewrites) you can use the `redirects` and `rewrites` keys in the `next.config.js` file in your project.

```javascript
module.exports = {
  async rewrites() {
    return [
      {
        source: '/about',
        destination: '/',
      },
    ];
  },
  async redirects() {
    return [
      {
        source: '/about',
        destination: '/',
        permanent: true,
      },
    ];
  },
};
```

#### 2\. Non-Next.js (`vercel.json`) Redirects

When using a framework without a built-in way to configure redirects you can create a `vercel.json` file in your project to set them up.

For each [redirect](https://vercel.com/docs/concepts/projects/project-configuration#redirects) and [rewrite](https://vercel.com/docs/concepts/projects/project-configuration#rewrites) you can use the `redirects` and `rewrites` keys in the `vercel.json` file in your project.

```json
{
  "redirects": [
    {
      "source": "/me",
      "destination": "/profile.html"
    },
    {
      "source": "/user",
      "destination": "/api/user",
      "permanent": false
    },
    {
      "source": "/view-source",
      "destination": "https://github.com/vercel/vercel"
    },
    {
      "source": "/:path((?!uk/).*)",
      "has": [
        {
          "type": "header",
          "key": "x-vercel-ip-country",
          "value": "GB"
        }
      ],
      "destination": "/uk/:path*",
      "permanent": false
    }
  ],
  "rewrites": [
    {
      "source": "/about",
      "destination": "/about-our-company.html"
    },
    {
      "source": "/resize/:width/:height",
      "destination": "/api/sharp"
    },
    {
      "source": "/proxy/:match*",
      "destination": "https://example.com/:match*"
    },
    {
      "source": "/:path((?!uk/).*)",
      "has": [
        {
          "type": "header",
          "key": "x-vercel-ip-country",
          "value": "GB"
        }
      ],
      "destination": "/uk/:path*"
    }
  ]
}
```

## Custom Headers

There are two ways currently to configure custom headers in Netlify:

- A plain text file called `_headers` without a file extension to the publish directory of your site in Netlify
  
- One or more `[[headers]]` tables in your Netlify configuration file `netlify.toml`
  

You will need to take note of all the headers set up in Netlify to properly configure them in Vercel.

### Gathering Netlify Headers Data

#### 1. `_headers` File

In a `_headers`file, you can specify one or several URL paths with their additional headers indented below them:

```text
# a path:
/templates/index.html
  # headers for that path:
  X-Frame-Options: DENY
  X-XSS-Protection: 1; mode=block
# another path:
/templates/index2.html
  # headers for that path:
  X-Frame-Options: SAMEORIGIN
/*
  X-Frame-Options: DENY
  X-XSS-Protection: 1; mode=block
```

#### 2. `netlify.toml` File Headers Data

In a `netlify.toml` file, each rule will be signified by a `[[headers]]` table which lists all the currently configured options for each route.

```text
[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
    X-XSS-Protection = "1; mode=block"
```

Once you have collected all the custom headers in your application you can start configuring them in Vercel. The method will depend on your application framework.

### Setup Headers on Vercel

Next.js has a built-in way to configure custom headers in your application and that is the preferred way to set them up in your application as they have precedence over platform-level configuration.

#### 1\. Next.js (`next.config.js`) Headers

For each [custom header](https://nextjs.org/docs/api-reference/next.config.js/headers) you can use the `headers` keys in the `next.config.js` file in your project.

```javascript
module.exports = {
  async headers() {
    return [
      {
        source: '/about',
        headers: [
          {
            key: 'x-custom-header',
            value: 'my custom header value',
          },
          {
            key: 'x-another-custom-header',
            value: 'my other custom header value',
          },
        ],
      },
    ];
  },
};
```

#### 2\. Non-Next.js (`vercel.json`) Headers

When using a framework without a built-in way to configure headers you can create a `vercel.json` file in your project to set them up.

For each [header](https://vercel.com/docs/concepts/projects/project-configuration#headers) you can use the `headers` key in the `vercel.json` file in your project.

```json
{
  "headers": [
    {
      "source": "/service-worker.js",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=0, must-revalidate"
        }
      ]
    },
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-XSS-Protection",
          "value": "1; mode=block"
        }
      ]
    },
    {
      "source": "/:path*",
      "has": [
        {
          "type": "query",
          "key": "authorized"
        }
      ],
      "headers": [
        {
          "key": "x-authorized",
          "value": "true"
        }
      ]
    }
  ]
}
```

## Serverless Functions

If using serverless functions outside of a framework like Next.js there will be a couple of steps involved to migrate them from Netlify to Vercel.

### 1. `API` Directory

Netlify has a similar file-based routing system for their Serverless Functions where they are placed in a folder called `functions/`, as opposed to `api/`.

To run them on Vercel, they are expected to be found in a directory called `api/`.

### 2\. Function Signature

The function signatures between Netlify and Vercel Functions are also different and will require some modification.

Netlify uses an `event` and `context` input that matches AWS Lambda functions. A TypeScript Netlify function will look like this:

```javascript
import { Handler } from '@netlify/functions';

const handler: Handler = async (event, context) => {
  return {
    statusCode: 200,
    body: JSON.stringify({ message: 'Hello World' }),
  };
};

export { handler };
```

Vercel uses a standard `Request` and `Response` API:

```tsx
export function GET(request: Request) {
  return new Response(`Hello from ${process.env.VERCEL_REGION}`);
}
```

## Routing Middleware

If using middleware outside of a framework like Next.js there will be a couple of steps involved to migrate them from Netlify to Vercel.

### 1\. Middleware Directory Structure

Netlify's Middleware structure differs from Vercel's file-based routing system. They are currently placed in a folder called `netlify/edge-functions` and require configuration in the `netlify.toml` file to match specific routes.

```text
[[edge_functions]]
path = "/test"
function = "hello"
```

To use [Routing Middleware](https://vercel.com/docs/routing-middleware) on Vercel, they are expected to be found in a single file called `middleware.ts` at the root of your project.

### 2\. Middleware Function Signature

The function signatures between Netlify and Vercel functions are also different and will require some modification.

Netlify uses a `request` and `context` input which matches the underlying Deno functions. A TypeScript Netlify function will look like this:

```tsx
import type { Context } from 'https://edge.netlify.com';

export default async (request: Request, context: Context) => {
  return context.rewrite('/about-2');
};
```

Vercel uses a standard `Request` input object and also requires a config object to match the middleware to specific routes:

```tsx
import { rewrite } from '@vercel/edge';

export function middleware(request: Request) {
  return rewrite(new URL('/about-2', request.url));
}
// config with a custom matcher
export const config = {
  matcher: '/test',
};
```