0.2.0 • Published 10 months ago

@supabase-labs/nextjs v0.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

Supabase 💚 Next.js

Use Supabase Auth in your Next.js app with ease.

!WARNING
This is a @supabase-labs experimental package. Expect breaking changes!

Installation

Install the package:

npm install @supabase-labs/nextjs

If you don't have them already installed, install the required peer dependencies:

npm install next @supabase/ssr @supabase/supabase-js

Usage

Configure Supabase using environment variables in your .env.local file:

NEXT_PUBLIC_SUPABASE_URL="<your-supabase-url>"
NEXT_PUBLIC_SUPABASE_ANON_KEY="<your-anon-key>"

Use supabaseMiddleware in your middleware.ts file:

import { supabaseMiddleware, createRouteMatcher } from '@supabase/nextjs/server'

const isPublicRoute = createRouteMatcher(['/login(.*)', '/signup(.*)'])

export default supabaseMiddleware(
  (auth, request) => {
    // protect all routes except the public ones
    if (!isPublicRoute(request)) {
      auth().protect()
    }

    // redirect to home if public route and user is logged in
    if (isPublicRoute(request) && auth().user) {
      auth().redirect("/")
    }
  },
  {
    paths: {
      // custom signIn path
      signIn: '/login'
    }
  }
)

export const config = {
  // don't run the middleware on static assets
  matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)']
}

In your components, use the Supabase Client to handle authentication:

Sign up

// app/signup/route.tsx
import { createClient } from '@supabase/nextjs/server'

export function SignUpForm() {
  async function signUp(formData: FormData) {
    'use server'
    const email = formData.get('email')
    const password = formData.get('password')
    const supabase = createClient()
    const { error } = await supabase.auth.signUp({
      email,
      password
    })
  }

  return (
    <form action={signUp}>
      <input type="email" name="email" />
      <input type="password" name="password" />
      <button>Sign Up</button>
    </form>
  )
}

Sign in

// app/login/route.tsx
import { createClient } from '@supabase/nextjs/server'

export function SignInForm() {
  async function signIn(formData: FormData) {
    'use server'
    const email = formData.get('email')
    const password = formData.get('password')
    const supabase = createClient()
    const { error } = await supabase.auth.signIn({
      email,
      password
    })
  }

  return (
    <form action={signIn}>
      <input type="email" name="email" />
      <input type="password" name="password" />
      <button>Sign in</button>
    </form>
  )
}

Sign out

// components/logout.tsx
import { redirect } from 'next/navigation'
import { createClient } from '@supabase/nextjs/server'

export function SignOutForm() {
  async function signOut() {
    'use server'
    const supabase = createClient()
    await supabase.auth.signOut()
    redirect('/')
  }

  return (
    <form action={signOut}>
      <button>Sign Out</button>
    </form>
  )
}

TypeScript

You can type your Supabase Client against your generated Supabase Database types.

Generate Supabase Database Types

Local database:

npx supabase gen types --lang=typescript --local > src/types/database.ts

Remote database:

npx supabase gen types --lang=typescript --project-id "<your-project-id>" > src/types/database.ts

Configure @supabase-labs/nextjs to use the generated types

You can configure @supabase-labs/nextjs to use the generated types in two ways:

Using Module Augmentation

This is the recommended approach. Your client will be directly typed against your database when you import it from @supabase-labs/nextjs.

!WARNING
You can only declare modules that you are actually importing in your project. For example if you're not importing @supabase-labs/nextjs/server anywhere in your project, the module declaration will fail.

// types/supabase.ts
import type { Database } from './types/database'

declare module '@supabase-labs/nextjs/server' {
  interface Register {
    database: Database
  }
}

// uncomment if you're using the Supabase Client client-side
// declare module '@supabase-labs/nextjs/client' {
//   interface Register {
//     database: Database
//   }
// }

Re-exporting the Supabase Client

This approach is useful if you want to customise the options of the Supabase Client.

// lib/supabase.ts
import { createClient as createSupabaseClient } from '@supabase/nextjs/server'
import type { Database } from '@/types/database'

export function createClient() {
  return createSupabaseClient<Database>(/* custom options */)
}

Credits

Props to Clerk for their excellent middleware API.

0.2.0

10 months ago

0.1.9

10 months ago

0.1.8

10 months ago

0.1.7

10 months ago

0.1.6

10 months ago

0.1.5

10 months ago

0.1.4

10 months ago

0.1.3

10 months ago

0.1.2

10 months ago

0.1.1

10 months ago