Limit Country Wise Access On Website Using Next.js
Tags: nextjs, vercel, middleware, typescript
Published: 2024-03-24 14:17:15

So, Came across a website whose access was limited to a specific countries. You might have encountered such tasks where you must limit the access to a website based on the country. This got be thinking how can I achieve this in Next.js. So in this blog, I will show you how to limit the access to a website based on the country using `next.js` and vercel.

## Prerequisites

- Basic knowledge of TypeScript
- Basic knowledge of Middleware
- Basic knowledge of Next.js

## Lets break down the task into smaller steps.

1. [Create a new Next.js project](#step-1-create-a-new-nextjs-project)
2. [Setup the project](#step-2-setup-the-project)
3. [Create middleware to limit the access to a website based on the country](#step-3-create-middleware-to-limit-the-access-to-a-website-based-on-the-country)
4. [Create a new route to test the functionality](#step-4-create-a-new-route-to-test-the-functionality)
5. [Deploy the project to Vercel](#step-5-create-a-new-route-to-test-the-functionality)
6. [Test the functionality](#step-6-schedule-the-task-to-run-the-functionality)

### Step 1: Create a new Next.js project

```bash
npx create-next-app nextjs-country-wise-access
cd nextjs-country-wise-access
```

### Step 2: Setup the project

To setup our projects we will setup pages which will be under this restriction and page/pages which will be open to all.
I will be typescript for this project. So let's get started.

```bash
mkdir pages/international
touch pages/international/index.ts
touch pages/index.ts
touch middleware.ts
```

### Step 3: Create middleware to limit the access to a website based on the country

```typescript
// middleware.ts
import { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'

const env = process.env.NODE_ENV
export default async function middleware(req: NextRequest) {
  const res = NextResponse.next()
  const pathname = req.nextUrl.pathname
  // Skip this middleware in development or if the path is international
  if (env !== 'development' && pathname !== '/international') {
    const country = req.geo?.country || req.headers.get('x-vercel-ip-country')
    // Here you can add the list of countries you want to allow, I have added IN and US for now
    if (!['IN', 'US'].includes(country ?? '')) {
      // Redirect to the international page if the country is not IN or US
      return NextResponse.redirect(new URL('/international', req.url))
    }
  }
  return res
}
```

### Step 4: Create a new route to test the functionality

```typescript
// pages/international/index.ts
export default function InternationalPage() {
  return (
    <div>
      <h1>International Page</h1>
      <p>This page is open to all</p>
    </div>
  )
}

// pages/index.ts
export default function HomePage() {
  return (
    <div>
      <h1>Home Page</h1>
      <p>This page is open to IN and US only</p>
    </div>
  )
}
```

### Step 5: Deploy the project to Vercel

You can deploy the project to vercel using their CLI or by connecting your github repository to vercel.

### Step 6: Test the functionality

You can test the functionality by visiting the deployed website and changing the country in the request header. You can use VPN to change the country in the request header.

## Conclusion

That's it! You have successfully limited the access to a website based on the country using Next.js and Vercel.