---
title: "Migration Guide"
description: "Learn how to migrate @nuxtjs/supabase to take advantage of JWT signing keys support"
canonical_url: "https://supabase.nuxtjs.org/getting-started/migration"
---
# Migration Guide

> Learn how to migrate @nuxtjs/supabase to take advantage of JWT signing keys support

This guide will help you migrate from `v1.x` to `v2.x`, which introduces support for Supabase's new JWT signing keys.

## 🔐 What are JWT Signing Keys?

Supabase has introduced a major security improvement by moving from symmetric to asymmetric JWT (JSON Web Token) signing. This change brings security and performance improvements in how your applications handle authentication.

### The Problem with Symmetric Keys

Previously, Supabase used a single shared secret key for both creating and verifying tokens. This meant your app had to constantly call `supabase.auth.getUser()` to check if sessions were valid, creating network delays calling the Supabase Auth server.

### The Solution with Asymmetric JWT Signing Keys

The new system uses two separate keys:

- A private key (kept secure by Supabase) for creating tokens.
- A public key (safe to share in your application) for verifying them.

Your application can now verify user sessions locally without contacting Supabase servers, making it faster and more reliable. This new key is named as `publishable key` on Supabase.

### Key Benefits

This upgrade eliminates authentication bottlenecks, improves security, and makes your applications work better at the edge (no extra calls to the Supabase Auth server).

<note to="https://supabase.com/blog/jwt-signing-keys">

Read the full technical explanation in the official Supabase blog post.

</note>

## 🚨 Breaking changes

### 1. `useSupabaseUser` Type Changes

`useSupabaseUser` now returns **JWT claims** instead of the full **User object**.

- **Before (v1.x):** `useSupabaseUser` returned the full `User` object from [auth.getUser()](https://supabase.com/docs/reference/javascript/auth-getuser)
- **After (v2.x):** `useSupabaseUser` returns `Claims` object from [auth.getClaims()](https://supabase.com/docs/reference/javascript/auth-getclaims) as a [JWT Payload](https://supabase.com/docs/guides/auth/jwts)

<code-group>

```json [auth.getUser() as .json]
{
  id: "11111111-1111-1111-1111-111111111111",
  aud: "authenticated",
  role: "authenticated",
  email: "example@email.com",
  email_confirmed_at: "2024-01-01T00:00:00Z",
  phone: "",
  confirmed_at: "2024-01-01T00:00:00Z",
  last_sign_in_at: "2024-01-01T00:00:00Z",
  app_metadata: {},
  user_metadata: {},
  identities: []
}
```

```json [auth.getClaims().claims as .json]
{
  session_id: "11111111-1111-1111-1111-111111111111",
  sub: "11111111-1111-1111-1111-111111111111",
  aud: "authenticated",
  role: "authenticated",
  email: "example@email.com",
  aal: "aal1",
  amr: [],
  exp: 1715769600,
  iat: 1715766000,
  is_anonymous: false,
  iss: "https://project-id.supabase.co/auth/v1",
  phone: "+13334445555",
  app_metadata: {},
  user_metadata: {},
  // identities is missing
  // last_sign_in_at is missing
  // confirmed_at is missing
  // email_confirmed_at is missing
}
```

</code-group>

<tip>

If you need the full User object, you'll need to explicitly call `auth.getUser()` but if you only need basic info (email, role...) no changes are required.

</tip>

### 2. Environment variables changes

**Remaining key** → **SUPABASE_KEY** is now storing the `publishable key` instead of the `anon key`

**New key** → **SUPABASE_SECRET_KEY** is now storing the `secret key` of your Supabase project

**Deprecated key** → **SUPABASE_SERVICE_KEY** was previously storing the `service_role key` but is now deprecated in favor of `SUPABASE_SECRET_KEY`

## 📋 Migration Steps

### 1. Types changes

The first thing you need to do is to ensure the `useSupabaseUser` changes do not affect your existing code.

<tip>

Once you've updated the types, you can already test your application and it should still work as expected.

</tip>

### 2. Environment variables changes

The **Good news** ☀️ is that everything will continue to work as-is with your existing `SUPABASE_KEY` (aka `anon key`).

Same for `SUPABASE_SERVICE_KEY`, if you're using it to bypass Row Level Security, you will face a deprecation warning but it will still work.

<warning to="https://supabase.com/blog/jwt-signing-keys">

However, we highly recommend you to enable JWT signing keys in your Supabase project and use your publishable key as `SUPABASE_KEY` and your secret key as `SUPABASE_SECRET_KEY`.

</warning>

#### 2.a. Enable JWT Signing Keys in Supabase Dashboard

Before migrating your environment variables, you need to enable JWT signing keys and thus create your JWT and API keys in your Supabase project:

<iframe width="560" height="315" src="https://www.youtube.com/embed/rwnOal_xRtM" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowFullScreen="true">



</iframe>

<tip>

**Watch this video tutorial** from **6:20 to 12:20** to understand how to enable JWT signing keys in your Supabase dashboard and get your new secret key.

</tip>

#### 2.b. Use your new keys in your `.env` file

```bash [.env]
NUXT_PUBLIC_SUPABASE_KEY=<your_publishable_key>
NUXT_SUPABASE_SECRET_KEY=<your_secret_key>
```

<tip>

The legacy `SUPABASE_KEY` and `SUPABASE_SECRET_KEY` env variables are still supported as fallbacks. See the [introduction](https://supabase.nuxtjs.org/getting-started/introduction) for details.

</tip>


## Sitemap

See the full [sitemap](https://supabase.nuxtjs.org/sitemap.md) for all pages.
