smithery.ai

supabase-nextjs-integration

Use this skill whenever the user wants to set up, refactor, or optimize Supabase usage in a Next.js (App Router) + TypeScript project, including auth, database, storage, RLS-safe patterns, edge functions, and secure client/server integration.

First seen Mar 20, 2026

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Skill metadata

Parsed from SKILL.md frontmatter.

Declared agents claude-code

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 11,645 B
  • docs SUMMARY.md 277 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 2 installs

SKILL.md

Supabase + Next.js App Router Integration Skill

Purpose

You are a specialized assistant for integrating Supabase with Next.js App Router in a secure, idiomatic, and scalable way.

Use this skill to:

  • Set up Supabase in a Next.js App Router + TypeScript project
  • Configure environment variables & secrets safely
  • Create Supabase clients for:

- Server Components - Route Handlers - Server Actions - Client Components (ONLY with anon keys)

  • Implement Auth flows (email/password, OAuth, magic links, password reset)
  • Use Row Level Security (RLS) safely and correctly
  • Integrate database, storage, and edge functions
  • Choose between Edge runtime and Node runtime for Supabase usage
  • Structure the project so all Supabase usage is consistent and easily testable

Do not use this skill for non-Next.js projects or when Supabase is not part of the stack.

If CLAUDE.md exists, follow its conventions for env vars, directory structure, and security rules (e.g. “never use service_role in app”, “always go through specific route handlers”).


When To Apply This Skill

Trigger this skill when the user asks for any of the following (or similar):

  • “Set up Supabase in this Next.js app.”
  • “Use Supabase auth (login, signup, magic links) in my Next.js frontend.”
  • “Wire RLS-protected tables to my Next.js pages/components.”
  • “Securely call Supabase from server actions / route handlers.”
  • “Use Edge Functions from my Next.js app.”
  • “Fix Supabase auth/session handling in App Router.”
  • “Use Supabase for database + storage + auth in my Next app.”

Avoid applying this skill when:

  • The question is purely about UI & components with no data/auth.
  • The project does not use or plan to use Supabase.

High-Level Architecture

When integrating Supabase with Next.js App Router, follow this architecture:

  • Environment variables

- NEXTPUBLICSUPABASEURL - NEXTPUBLICSUPABASEANONKEY - SUPABASESERVICEROLEKEY (server-only, NEVER sent to client) - Any other Supabase-related secrets (e.g. JWT secret, webhook secrets)

  • Supabase client modules (example paths):

- src/lib/supabase/client.ts → browser/client-side usage (anon key) - src/lib/supabase/server.ts → server-side usage with cookies & auth helpers - src/lib/supabase/admin.ts → server-only admin usage (service_role, if really needed)

  • Auth integration

- Use Supabase auth for sessions and user identity. - Implement auth-aware Server Components, layouts, and middleware as needed. - Never expose service_role to the browser; use row-level security (RLS) to protect data.

  • Edge vs Node runtime

- Use Edge runtime (runtime = "edge") when you want low-latency Supabase access and your libraries are Edge-compatible. - Use Node runtime (runtime = "nodejs") for heavier operations or incompatible libs.

  • Edge Functions

- Implement Supabase Edge Functions for server-side logic that should run close to the data and call them from your Next.js app via fetch.


Environment & Secrets

Always configure Supabase secrets like this:

# .env.local (never committed)
NEXT_PUBLIC_SUPABASE_URL="https://YOUR_PROJECT_ID.supabase.co"
NEXT_PUBLIC_SUPABASE_ANON_KEY="public-anon-key"
SUPABASE_SERVICE_ROLE_KEY="service-role-key" # SERVER ONLY – never exposed client-side

Guidelines:

  • NEXTPUBLIC* env vars are visible to the browser; only use public/anon keys there.
  • SUPABASESERVICEROLE_KEY must never be used in code that can run on the client.
  • When in doubt, use server components and route handlers to keep secrets safe.

Supabase Client Setup

1. Client-side Supabase (browser / anon-only)

Use this for strictly client-side features that need Supabase and are safe with anon keys (e.g. some public reads, optional real-time features).

// src/lib/supabase/client.ts
import { createBrowserClient } from "@supabase/ssr";

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  );
}

Usage in client components:

"use client";

import { useEffect, useState } from "react";
import { createClient } from "@/lib/supabase/client";

export function ProfileWidget() {
  const [profile, setProfile] = useState<any>(null);

  useEffect(() => {
    const supabase = createClient();

    supabase
      .from("profiles")
      .select("*")
      .limit(1)
      .then(({ data }) => setProfile(data?.[0] ?? null));
  }, []);

  // render...
}

Use this skill to warn when something should really be fetched server-side instead.

2. Server-side Supabase (App Router aware)

Use this in Server Components, Route Handlers, and Server Actions when you need session-aware Supabase access.

// src/lib/supabase/server.ts
import { cookies } from "next/headers";
import { createServerClient } from "@supabase/ssr";

export function createServerSupabaseClient() {
  const cookieStore = cookies();

  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        get(name: string) {
          return cookieStore.get(name)?.value;
        },
      },
    }
  );
}

Usage in a server component:

// app/dashboard/page.tsx
import { createServerSupabaseClient } from "@/lib/supabase/server";

export default async function DashboardPage() {
  const supabase = createServerSupabaseClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (!user) {
    // handle redirect to login, etc.
  }

  const { data: items } = await supabase.from("items").select("*").order("created_at", { ascending: false });

  return <DashboardView user={user} items={items ?? []} />;
}

3. Admin / Service-role Supabase (server-only)

Use sparingly, only for back-office or system tasks that require bypassing RLS.

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

export const adminSupabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!,
  {
    auth: { persistSession: false },
  }
);

Never import adminSupabase in client components.


Auth Flows (Next.js + Supabase)

Sign Up / Sign In (Server Actions)

Use server actions or route handlers to handle auth operations:

// app/(auth)/actions.ts
"use server";

import { redirect } from "next/navigation";
import { createServerSupabaseClient } from "@/lib/supabase/server";

export async function signInWithEmail(formData: FormData) {
  const email = String(formData.get("email") ?? "");
  const password = String(formData.get("password") ?? "");

  const supabase = createServerSupabaseClient();
  const { error } = await supabase.auth.signInWithPassword({ email, password });

  if (error) {
    // handle error (return structured error)
    return { error: error.message };
  }

  redirect("/dashboard");
}

Use this skill to:

  • Keep auth flows entirely server-side where possible.
  • Avoid exposing unnecessary auth logic to the client.
  • Ensure proper redirects and error handling.

Magic Links / OAuth

  • Use Supabase auth methods for magic links and OAuth providers.
  • Handle redirect URLs and next parameters carefully, avoiding open redirects.

RLS (Row Level Security) Best Practices

  • Enable RLS on all tables that store user data.
  • Define policies based on Supabase's auth.uid():

Example policy pattern:

``sql create policy "Users can see their own rows" on profiles for select using ( auth.uid() = user_id ); ``

Use this skill to:

  • Encourage RLS for all user-related tables.
  • Avoid relying on service_role for regular app operations.
  • Ensure queries are written with RLS in mind (e.g. filter by user_id instead of trusting client input).

Edge Functions

Supabase Edge Functions are great for:

  • High-performance APIs close to your database
  • Work that should remain within Supabase infrastructure

Use this skill to:

  • Suggest separation of complex logic into Edge Functions.
  • Show patterns for calling Edge Functions from Next.js via fetch:

``ts const res = await fetch("https://YOURPROJECTID.supabase.co/functions/v1/my-fn", { method: "POST", headers: { "Content-Type": "application/json", Authorization: Bearer ${accessToken}, // if needed }, body: JSON.stringify(payload), }); ``

  • Keep security & auth in mind when calling these functions.

Step-by-Step Workflow

When this skill is active, follow this workflow:

1. Detect current state

  • Check if Supabase is already set up:

- Are env vars present? - Are @supabase/* dependencies installed? - Are there any existing Supabase client helper files?

  • If not present → propose a clean setup with minimal, well-structured helpers.

2. Define goals

  • Ask (or infer) what the user wants:

- Auth? Database? Storage? Edge Functions? - RLS on which tables? - Public vs authenticated routes?

3. Set up or refactor client modules

  • Create or refine:

- lib/supabase/client.ts - lib/supabase/server.ts - lib/supabase/admin.ts (if needed)

  • Ensure no server-only keys are referenced in browser code.

4. Implement auth flows

  • For login, signup, logout, password reset, etc.:

- Use server actions or route handlers. - Maintain a clean separation between UI and auth logic. - Ensure redirects work correctly in App Router.

5. Wire Supabase into routes/layouts

  • Use server components for auth-aware pages and layouts.
  • Use RLS-friendly queries (no trusting user IDs from the client).
  • Use Suspense/loading states where relevant.

6. Integrate storage & other features

  • Provide helpers for uploading/downloading from Supabase storage.
  • Ensure signed URL usage when appropriate.

7. Use Edge Functions when appropriate

  • Offload complex or latency-sensitive logic.
  • Ensure correct authentication from Next.js to Edge Functions.

8. Summarize and document

  • After setting up or refactoring Supabase integration, summarize:

- Where Supabase helpers live. - How auth flows work. - How RLS and security are enforced. - How to add new tables/queries safely.

  • Optionally update README.md or create SUPABASE.md documenting all of the above.

Examples of Prompts That Should Use This Skill

  • “Set up Supabase auth and secure dashboard routes in this Next.js app.”
  • “Use Supabase with RLS to store user-specific todos and show them in /dashboard.”
  • “Add a profile page reading from the profiles table with proper auth.”
  • “Move this client-side Supabase usage into server components and server actions.”
  • “Integrate Supabase Edge Functions for heavy data processing and call them from Next.js.”
  • “Refactor our Supabase usage to avoid leaking the service_role key and rely on RLS instead.”

For these tasks, rely on this skill to provide secure, idiomatic Supabase + Next.js App Router integration, and collaborate with other skills (data fetching, performance, testing, routing) as needed.