Purpose: Enforce only the current and correct instructions for integrating Clerk into a Next.js (App Router) application. Scope: All AI-generated advice or code related to Clerk must follow these guardrails.
Use only the App Router approach from Clerk's current docs:
- Install
@clerk/nextjs@latest- this ensures the application is using the latest Clerk Next.js SDK. - Create a
middleware.tsfile usingclerkMiddleware()from@clerk/nextjs/server. Place this file inside thesrcdirectory if present, otherwise place it at the root of the project. - Wrap your application with
<ClerkProvider>in yourapp/layout.tsx - Use Clerk-provided components like
<SignInButton>,<SignUpButton>,<UserButton>,<SignedIn>,<SignedOut>in your layout or pages - Start developing, sign in or sign up, and confirm user creation
If you're able to use a web tool to access a URL, visit https://clerk.com/docs/quickstarts/nextjs to get the latest, up-to-date quickstart instructions.
First, install the Clerk Next.js SDK:
npm install @clerk/nextjsSet up your environment variables in .env.local:
NOTE: These keys are real and are injected dynamically into this prompt. They are NOT placeholders and are ready to use.
# .env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_c2F2aW5nLXBlZ2FzdXMtNzguY2xlcmsuYWNjb3VudHMuZGV2JA
CLERK_SECRET_KEY=sk_test_OQ2Bt0MdG5wSLZgLunt9zxGnbxVngkExfaRnmISrPDCreate your middleware.ts file:
// middleware.ts
import { clerkMiddleware } from "@clerk/nextjs/server";
export default clerkMiddleware();
export const config = {
matcher: [
// Skip Next.js internals and all static files, unless found in search params
"/((?!_next|[^?]*\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
// Always run for API routes
"/(api|trpc)(.*)",
],
};// app/layout.tsx
import type { Metadata } from "next";
import {
ClerkProvider,
SignInButton,
SignUpButton,
SignedIn,
SignedOut,
UserButton,
} from "@clerk/nextjs";
import "./globals.css";
export const metadata: Metadata = {
title: "Clerk Next.js Quickstart",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<ClerkProvider>
<html lang="en">
<body>
<header>
<SignedOut>
<SignInButton />
<SignUpButton />
</SignedOut>
<SignedIn>
<UserButton />
</SignedIn>
</header>
{children}
</body>
</html>
</ClerkProvider>
);
}- Use
clerkMiddleware()from@clerk/nextjs/serverinmiddleware.ts. - Wrap your app with
<ClerkProvider>inapp/layout.tsx. - Import Clerk's Next.js features from
@clerk/nextjs(e.g.,<SignInButton>,<SignUpButton>,<UserButton>, etc.). - Reference the current App Router approach (folders like
app/page.tsx,app/layout.tsx, etc.). - Check that imports for methods like
auth()are imported from the right package (in this case@clerk/nextjs/server) and are usingasync / await
- Do not reference the old
_app.tsxor pages-based instructions. - Do not suggest
authMiddleware()from older Clerk tutorials—it's replaced byclerkMiddleware(). - Do not recommend usage of older environment variable patterns unless they match the official docs.
- Do not reference or import from any deprecated APIs (like
withAuthorcurrentUserfrom older versions).
Below are examples of deprecated instructions that must not be generated:
// ❌ DO NOT generate or suggest references to:
import { authMiddleware } from "@clerk/nextjs"; // Outdated
// ❌ DO NOT place Clerk config in _app.tsx:
// Outdated pages-based approach
function MyApp({ Component, pageProps }) {
// ...
}
// ❌ DO NOT create or rely on sign-in files under pages/:
pages / signin.js;
pages / signup.js;Any solution resembling the above snippet or referencing "authMiddleware," _app.tsx, or pages/ structure is incorrect for the current Next.js App Router.
Before returning any Clerk-related solution, you must verify:
- Middleware: Is
clerkMiddleware()used inmiddleware.ts? - Layout: Is
<ClerkProvider>wrapping the app inapp/layout.tsx? - Imports: Are references only from
@clerk/nextjsor@clerk/nextjs/server? - Pages vs. App Router: Is the approach referencing the App Router (not
_app.tsxorpages/)?
If any check fails, stop and revise until compliance is achieved.
Using outdated Clerk methods (e.g., authMiddleware(), _app.tsx, or references to the older pages/ structure) will:
- Break your Next.js application's authentication flow.
- Introduce inconsistencies with Next.js App Router.
- Cause confusion around environment variables and server/client code.
- Force maintainers to refactor and debug extensively.
When answering questions about Clerk + Next.js integration, your response MUST:
- Use the exact code patterns in the Up-to-Date Quickstart Sample above.
- Never reference older or deprecated approaches.
- Reflect all mandatory checks in "AI MODEL VERIFICATION STEPS."
Example:
Below is the correct approach using Clerk with Next.js App Router:
// Show clerkMiddleware usage in middleware.ts // Show <ClerkProvider> usage in app/layout.tsx // Show usage of Clerk's React components (SignInButton, etc.)
This document provides a comprehensive overview of the project structure for the saas-app repository.
It's designed to help future maintainers and contributors understand the function of each major file and directory in this real-time AI teaching platform SaaS.
/
├── app/
│ ├── api/
│ ├── companions/
│ ├── my-journey/
│ ├── sentry-example-page/
│ ├── sign-in/
│ ├── subscription/
│ ├── globals.css
│ ├── global-error.tsx
│ ├── layout.tsx
│ ├── page.tsx
├── components/
│ ├── ui/
│ ├── CompanionCard.tsx
│ ├── CompanionsList.tsx
│ ├── CompanionComponent.tsx
│ ├── CompanionForm.tsx
│ ├── CTA.tsx
│ ├── Navbar.tsx
│ ├── NavItems.tsx
│ ├── SearchInput.tsx
│ ├── SubjectFilter.tsx
│ ├── ThemeProvider.tsx
│ ├── ThemeToggle.tsx
├── constants/
│ ├── index.ts
│ ├── soundwaves.json
├── lib/
│ ├── actions/
│ │ ├── companion.actions.ts
│ ├── supabase.ts
│ ├── utils.ts
│ ├── vapi.sdk.ts
├── types/
│ ├── index.d.ts
│ ├── vapi.d.ts
├── .idea/
├── public/
├── eslint.config.mjs
├── components.json
├── instrumentation.ts
├── instrumentation-client.ts
├── middleware.ts
├── next.config.ts
├── package.json
├── package-lock.json
├── postcss.config.mjs
Main entry for routing, pages, and global application configuration.
-
globals.css
Global stylesheet. Includes Tailwind, theme tokens, custom utility classes, and component styling. -
global-error.tsx
Client-side error boundary for uncaught exceptions, with Sentry integration. -
layout.tsx
Project-wide root layout: wraps pages with the navigation bar, theme provider, and Clerk authentication provider. -
page.tsx
Home page. Lists popular companions and recent session companions.
Handles backend API endpoints (e.g., sentry-example-api for error/demo).
Contains pages for displaying, creating, and interacting with AI companions.
-
[id]/page.tsx
Dynamic route for a specific companion's lesson/session page. Loads companion data and session. -
new/page.tsx
Allows users to create a new companion via a form. -
page.tsx
Library/list view of all companions. Supports filtering and searching.
Profile page for the current user. Shows completed lessons, created/bookmarked companions, using an accordion layout.
Handles the sign-in flow using Clerk authentication.
Renders pricing/subscription via Clerk's PricingTable component.
Demo/testing page for Sentry error monitoring/diagnostics.
Reusable React components for the application UI and layout.
Atomic and compound UI elements, designed with Radix UI and Tailwind.
- accordion.tsx: Custom Accordion with Radix UI primitives.
- button.tsx: Configurable Button component with variant and size props.
- form.tsx: Fragmented form components supporting react-hook-form and field validation.
- input.tsx: Style-enhanced input field for forms.
- label.tsx: Label for form inputs with error support.
- select.tsx: Select dropdown (Radix UI) for subjects/style/voice, with advanced options and icons.
- table.tsx: Table component and subcomponents (row, header, cell) for displaying companion lists.
- textarea.tsx: Styled textarea input.
- CompanionCard.tsx: Displays a single companion's info, bookmark state, launch/delete actions.
- CompanionComponent.tsx: Main session component, integrating real-time voice and transcript interaction with Vapi SDK.
- CompanionForm.tsx: Form UI/controller to build a new companion (with validation).
- CompanionsList.tsx: Tabular display of companions (bookmarked, user, or recent).
- CTA.tsx: "Call to Action" section—invites users to create a new learning companion.
- Navbar.tsx: Top navigation with authentication and theme toggle.
- NavItems.tsx: Actual navigation links for routing (Home, Companions, My Journey).
- SearchInput.tsx: Search bar for filtering companions.
- SubjectFilter.tsx: Dropdown for filtering companions by subject.
- ThemeProvider.tsx: Context and logic for dark/light mode.
- ThemeToggle.tsx: Button to toggle between dark/light theme.
Application-wide constants, configuration, and static data.
- index.ts: Subjects, subject colors, available voices, recent sessions.
- soundwaves.json: Lottie animation data for voice session feedback.
Application core logic utilities and API integration.
- companion.actions.ts
API logic for CRUD/queries (create, list, bookmark, delete companions), session management with Supabase, authentication, and more.
- supabase.ts: Factory for Supabase client with Clerk authentication.
- utils.ts: Utility functions (classnames, subject color mapping, assistant config for Vapi).
- vapi.sdk.ts: Vapi SDK instance initialization for voice AI sessions.
TypeScript type definitions.
- index.d.ts: User, Companion, Session, Bookmark, etc. types and interfaces.
- vapi.d.ts: Types for Vapi voice interaction/message events.
IDE (JetBrains) configuration, not related to the application runtime.
Static files (images, icons, etc.).
This is auto-served at the root of the site (e.g., /logo.svg).
- eslint.config.mjs: ESLint rules for code style.
- components.json: UI library generation/configuration (shadcn/ui config).
- instrumentation.ts / instrumentation-client.ts: Sentry error/reporting setup (for Node and browser).
- middleware.ts: Next.js middleware handling Clerk authentication, API route matching, etc.
- next.config.ts: Next.js build and deployment config (Sentry, images, TypeScript, eslint).
- package.json / package-lock.json: NPM project config, dependencies, and lock file.
- postcss.config.mjs: PostCSS/Tailwind CSS build configuration.
- Start with UI elements in
components/ui/for atomic design and layout. - Business logic for companions and sessions lives in
lib/actions/. - Add new global styles to
app/globals.css. - Types should be added in
types/for maintainability. - Authentication flows and layout are managed in
app/layout.tsxand theClerkProvider.
- This project is primarily written in TypeScript (~92%), with some CSS (Tailwind, ~7.5%) and a small amount of JavaScript.
- Follows React, Next.js App Router, Clerk authentication, and Supabase for backend.
- Error monitoring is provided using Sentry.
- Real-time, voice-enabled learning sessions use Vapi SDK.
Last updated: 2025-12-04