Supabase Auth

Supabase gives you a full Postgres database, authentication, and storage . @supabase/supabase-js comes pre-installed. Connect your project, set up your env vars, and you're ready to handle signups, logins, and protected routes.

Last updated: 2026-03-29

Connect Your Supabase Project

Create a project on supabase.com, grab your Project URL and anon key from Settings → API, and add them to your .env file. The client is already wired up in the template.

.env
# .env
PUBLIC_SUPABASE_URL=https://your-project.supabase.co
PUBLIC_SUPABASE_ANON_KEY=your-anon-key

Initialize the Client

Create a shared Supabase client so you import it once across your app. Use PUBLIC_ prefix so it's available in both Astro server and React client components.

src/lib/supabase.ts
// src/lib/supabase.ts
import { createClient } from '@supabase/supabase-js';

export const supabase = createClient(
  import.meta.env.PUBLIC_SUPABASE_URL,
  import.meta.env.PUBLIC_SUPABASE_ANON_KEY
);

Sign In & Sign Up

Use Supabase Auth to register and log in users with email/password, magic link, or OAuth. Astro API routes handle the server-side flow cleanly.

Terminal
// Sign up
const { data, error } = await supabase.auth.signUp({
  email: 'user@example.com',
  password: 'secure-password',
});

// Sign in
const { data, error } = await supabase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'secure-password',
});

// Sign out
await supabase.auth.signOut();

Protect Routes with Middleware

Use Astro middleware to check the session server-side and redirect unauthenticated users away from protected pages.

src/middleware.ts
// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { supabase } from './lib/supabase';

export const onRequest = defineMiddleware(async ({ url, redirect }, next) => {
  const protectedRoutes = ['/dashboard', '/account'];
  const isProtected = protectedRoutes.some(r => url.pathname.startsWith(r));

  if (isProtected) {
    const { data: { session } } = await supabase.auth.getSession();
    if (!session) return redirect('/signin');
  }

  return next();
});