Repo type: Next.js (App Router) + TypeScript + Tailwind + shadcn/ui + Supabase Auth (SSR via @supabase/ssr)
Common commands (npm)
- Install dependencies (uses package-lock.json):
npm ci - Start dev server (Turbopack):
npm run dev - Lint:
npm run lint - Lint with autofix:
npx next lint --fix - Type-check only:
npx tsc --noEmit - Build:
npm run build - Start in production (after build):
npm run start - Tests: not configured in this repo (no test runner or test script present)
- Run a single test: not applicable (tests are not set up)
Environment setup
- Copy
.env.exampleto.env.localand set:NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_PUBLISHABLE_OR_ANON_KEY
- Supabase Auth redirect URL for local dev must be whitelisted in your Supabase project:
http://localhost:3000/auth/callback
- When env vars are missing, the app renders onboarding steps and the auth middleware becomes a no-op via
hasEnvVars.
High-level architecture
-
App Router structure (server-first)
app/contains the root layout and routes.app/layout.tsxsets up global styles, metadata, andnext-themestheme provider.app/page.tsxis the landing page. It gates content based onhasEnvVarsto show either connection steps or sign-up steps.app/protected/is a protected area. Server component fetches auth claims; unauthenticated users are redirected to login.
- Auth flow routes under
app/auth/:app/auth/callback/route.ts: Handles OAuth/code exchange viasupabase.auth.exchangeCodeForSessionand redirects to thenextparam (defaults to/protected).app/auth/confirm/route.ts: Handles email OTP verification viasupabase.auth.verifyOtp.app/auth/login|sign-up|forgot-password|update-password|sign-up-success|error: UI routes for auth flows.
-
Supabase client layers (
lib/supabase/*)lib/supabase/server.tscreates a server-side client with cookie integration usingcreateServerClient. Important: create a fresh client per request; do not store globally.lib/supabase/client.tscreates a browser client viacreateBrowserClientfor client components.lib/supabase/middleware.tsexportsupdateSessionwhich:- Hydrates a
NextResponse, creates a per-request server client, callssupabase.auth.getClaims()to validate the session, and optionally redirects unauthenticated users to/auth/loginfor non-auth routes. - Returns the original
supabaseResponseto preserve cookies. If you need to change the response, follow the comments in that file to avoid desyncing cookies. - Caution: Avoid adding logic between client creation and
getClaims()(see in-file notes) to prevent hard-to-debug session issues.
- Hydrates a
-
Next.js middleware (
middleware.ts)- Delegates to
updateSession(request)and defines amatcherthat excludes_next/static,_next/image,favicon.ico, and common image file extensions from auth checks. - If you add other public assets or routes that should bypass auth, update the
matcheraccordingly.
- Delegates to
-
UI & theming
- Tailwind configured via
tailwind.config.tsandpostcss.config.mjs; base styles inapp/globals.css. - Components follow shadcn/ui patterns (
components/ui/*) and useclass-variance-authorityfor variants. - Theme toggling via
next-themes(ThemeProviderin root layout) and aThemeSwitchercomponent. - Utility
cn()for class merging lives inlib/utils.ts(clsx + tailwind-merge).
- Tailwind configured via
-
Tooling & config
- TypeScript strict build with bundler module resolution and path alias
@/*(seetsconfig.json). - ESLint FlatConfig compatibility setup extending
next/core-web-vitalsandnext/typescript(eslint.config.mjs). components.jsondefines shadcn/ui aliases (e.g.,@/components,@/lib,@/components/ui) consistent with TS path aliases.next.config.tsis currently minimal.
- TypeScript strict build with bundler module resolution and path alias
Development tips specific to this codebase
- Auth enforcement happens in both middleware and in
app/protectedserver components. If you change the auth flow, update both the middleware matcher/logic and any server component guards to keep behavior consistent. - The onboarding guard
hasEnvVars(inlib/utils.ts) intentionally disables middleware auth until Supabase env vars are provided. Keep this behavior if you want the template to be usable before configuration; remove it when you fully wire up your project. - When editing
lib/supabase/middleware.ts, ensure you always return thesupabaseResponseand preserve cookies as documented in code comments to prevent session loss.