# Next.js

## Prerequisites

Create a [Next.js app](https://nextjs.org/docs/app/getting-started/installation).

## Install

In your Next.js project, install Dotenvx and [@dotenvx/next-env](https://www.npmjs.com/package/@dotenvx/next-env).

**npm**

```console
$ npm install @dotenvx/dotenvx
$ npm install @dotenvx/next-env
```

**pnpm**

```console
$ pnpm add @dotenvx/dotenvx
$ pnpm add @dotenvx/next-env
```

Add this override to your package manager’s configuration:

**npm — package.json**

```json
{
  "overrides": {
    "@next/env": "npm:@dotenvx/next-env"
  }
}
```

**pnpm — pnpm-workspace.yaml**

```yaml
overrides:
  "@next/env": "npm:@dotenvx/next-env"
```

Apply it:

**npm**

```console
$ npm install
```

**pnpm**

```console
$ pnpm install
```

Next.js now loads encrypted secrets automatically through @dotenvx/next-env.

## Encrypt

Start with a secret value in the .env file at your project root, like:

```dotenv
# .env
HELLO="Secret"
```

Encrypt it with a single command.

**npm**

```console
$ npx dotenvx encrypt
◈ encrypted .env (022 0D8) via .env.keys ⛉
```

**pnpm**

```console
$ pnpm exec dotenvx encrypt
◈ encrypted .env (022 0D8) via .env.keys ⛉
```

The values become ciphertext and only your private key can unlock them.

```dotenv
# .env
DOTENV_PUBLIC_KEY="0220d830351410598be484f43a7b07097e09851f50426832876e8b5815a1752990"

HELLO="encrypted:BHLTACNJMr00nTG6yXpkCyWFKF/MY0ajN855tg3uVtKopTe2AGzSkQlcPd21pTOT3Ci8IKrdIg2TMZFoq1mDR6yb06QCRvqHXtpkZkAHYCEHfeWqqC8tMFovcYq5JS2uZSrC/qUGDA=="
```

## Commit

Commit your encrypted .env files with your code. It's safe. Now you can securely share secrets through git. Keep .env.keys out of git. The -f flag adds the encrypted file even if your Next.js project ignores .env files.

```console
$ git add -f .env
$ git commit -m "encrypt .env"
```

## Ship

Read your secrets through process.env. Create app/api/hello/route.js:

```javascript
// app/api/hello/route.js
import { connection } from 'next/server'

export async function GET() {
  await connection()
  return new Response(`Hello ${process.env.HELLO}`)
}
```

Run your app:

**npm**

```console
$ npm run dev
⟐ injected env (2) from .env (022 0D8) via .env.keys
▲ Next.js 16.4.1 (Turbopack)
- Local:         http://localhost:3000
```

**pnpm**

```console
$ pnpm dev
⟐ injected env (2) from .env (022 0D8) via .env.keys
▲ Next.js 16.4.1 (Turbopack)
- Local:         http://localhost:3000
```

Next.js loads and decrypts .env before your server code reads process.env.

Visit [http://localhost:3000/api/hello](http://localhost:3000/api/hello) to see Hello Secret.

Browser response at [http://localhost:3000/api/hello](http://localhost:3000/api/hello):

```text
Hello Secret
```

[**Seeing encrypted:ciphertext only?** Troubleshoot →](https://dotenvx.com/docs/nextjs/encrypted-text.md)

## Share

Have teammates? Share access with Dotenvx Armor ⛨

Log in to Dotenvx.

**npm**

```console
$ npx dotenvx login
◉ logged in (username)
```

**pnpm**

```console
$ pnpm exec dotenvx login
◉ logged in (username)
```

Create the Armored Key ⛨

**npm**

```console
$ npx dotenvx armor up
⛨ armored .env (022 0D8)
```

**pnpm**

```console
$ pnpm exec dotenvx armor up
⛨ armored .env (022 0D8)
```

Invite your teammate.

**npm**

```console
$ npx dotenvx armor invite
⛨ invited person@example.com to team
```

**pnpm**

```console
$ pnpm exec dotenvx armor invite
⛨ invited person@example.com to team
```

They can now pull (git), decrypt, and run.

**npm**

```console
$ npm run dev
⟐ injected env (2) from .env (022 0D8) via Armor ⛨
▲ Next.js 16.4.1 (Turbopack)
- Local:         http://localhost:3000
```

**pnpm**

```console
$ pnpm dev
⟐ injected env (2) from .env (022 0D8) via Armor ⛨
▲ Next.js 16.4.1 (Turbopack)
- Local:         http://localhost:3000
```

Browser response at [http://localhost:3000/api/hello](http://localhost:3000/api/hello):

```text
Hello Secret
```

[**Not using Armor?** Alternative →](https://dotenvx.com/docs/nextjs/share-private-key.md)

## Production

Create a .env.production file.

```dotenv
# .env.production
HELLO="Production"
```

Encrypt it with an Enclaved Key ◊

**npm**

```console
$ npx dotenvx encrypt -f .env.production
◈ encrypted .env.production (022 0D8) via Armor Enclave ◊
```

**pnpm**

```console
$ pnpm exec dotenvx encrypt -f .env.production
◈ encrypted .env.production (022 0D8) via Armor Enclave ◊

# 1. ⛨ Choose key type …
# ❯ ◊ Enclaved
# 2. ◊ Select service …
# ❯ Vercel
# 3. ◊ Select connection …
# 4. ◊ Select resource/project …
# 5. ? Private key name › DOTENV_PRIVATE_KEY_PRODUCTION
```

Commit .env.production.

```console
$ git add -f .env.production
$ git commit -m "encrypt .env.production"
```

Deploy to Vercel.

**npm**

```console
$ npm install vercel --save-dev
$ npx vercel --prod
```

**pnpm**

```console
$ pnpm add -D vercel
$ pnpm exec vercel --prod
```

Vercel loads and decrypts .env.production with your Enclaved Key ◊

Visit [https://your-app.vercel.app/api/hello](https://your-app.vercel.app/api/hello) to see Hello Production.

Browser response at [https://your-app.vercel.app/api/hello](https://your-app.vercel.app/api/hello):

```text
Hello Production
```

[**Not using Armor Enclaves?** Alternative →](https://dotenvx.com/docs/nextjs/deploy-private-key.md)

## Conclusion

You've encrypted your secrets, shared access with Armor, and deployed to Vercel with Armor Enclaves.
