Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
997838b
fix: conditionally show login/logout in auth0 example nav
nicknisi Feb 2, 2026
4272c97
chore: add .next/ to gitignore
nicknisi Feb 2, 2026
8a81d24
chore: run the formatter
nicknisi Feb 2, 2026
1b9ddd4
fix(skill): make AuthKitProvider requirement explicit in nextjs skill
nicknisi Feb 2, 2026
219a834
chore: add .react-router/ to gitignore
nicknisi Feb 2, 2026
b660c0a
fix(evals): allow AuthKitProvider in extracted provider file
nicknisi Feb 2, 2026
c6107f0
feat(evals): add success criteria validation and skill versioning
nicknisi Feb 2, 2026
24975ca
feat(evals): add edge case test fixtures for all frameworks
nicknisi Feb 2, 2026
68d36a4
feat(evals): add latency tracking for performance metrics
nicknisi Feb 2, 2026
588c5af
feat(evals): add LLM-based quality grading with --quality flag
nicknisi Feb 2, 2026
a4c76ae
fix(evals): initialize git in fixtures for quality diff capture
nicknisi Feb 2, 2026
ec3d5ac
fix(evals): exclude node_modules and lock files from quality diff
nicknisi Feb 3, 2026
770aeef
fix(evals): truncate large diffs to avoid rate limits
nicknisi Feb 3, 2026
20d312b
fix(evals): exclude build directories from quality diff
nicknisi Feb 3, 2026
13b2394
refactor(evals): capture only source files in quality diff
nicknisi Feb 3, 2026
3be3b53
feat(evals): show quality reasoning in verbose mode
nicknisi Feb 3, 2026
924875a
fix(evals): exclude node_modules from source file diff
nicknisi Feb 3, 2026
a094d87
refactor(evals): use key files instead of raw diff for quality grading
nicknisi Feb 3, 2026
af273d4
feat(evals): add diff, history, and prune commands
nicknisi Feb 3, 2026
e3f0415
refactor(evals): use chain-of-thought prompting for quality grading
nicknisi Feb 3, 2026
4b7d060
fix(evals): show all fixture states in results matrix
nicknisi Feb 3, 2026
9c2a313
feat(nextjs): support authkit() composable for existing middleware
nicknisi Feb 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ dist/

# Eval results
tests/eval-results/
.next/
.react-router/
83 changes: 73 additions & 10 deletions skills/workos-authkit-nextjs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,45 @@ Next.js version?

Middleware/proxy code: See README for `authkitMiddleware()` export pattern.

### Existing Middleware (IMPORTANT)

If `middleware.ts` already exists with custom logic (rate limiting, logging, headers, etc.), use the **`authkit()` composable function** instead of `authkitMiddleware`.

**Pattern for composing with existing middleware:**

```typescript
import { NextRequest, NextResponse } from 'next/server';
import { authkit, handleAuthkitHeaders } from '@workos-inc/authkit-nextjs';

export default async function middleware(request: NextRequest) {
// 1. Get auth session and headers from AuthKit
const { session, headers, authorizationUrl } = await authkit(request);
const { pathname } = request.nextUrl;

// 2. === YOUR EXISTING MIDDLEWARE LOGIC ===
// Rate limiting, logging, custom headers, etc.
const rateLimitResult = checkRateLimit(request);
if (!rateLimitResult.allowed) {
return new NextResponse('Too Many Requests', { status: 429 });
}

// 3. Protect routes - redirect to auth if needed
if (pathname.startsWith('/dashboard') && !session.user && authorizationUrl) {
return handleAuthkitHeaders(request, headers, { redirect: authorizationUrl });
}

// 4. Continue with AuthKit headers properly handled
return handleAuthkitHeaders(request, headers);
}
```

**Key functions:**
- `authkit(request)` - Returns `{ session, headers, authorizationUrl }` for composition
- `handleAuthkitHeaders(request, headers, options?)` - Ensures AuthKit headers pass through correctly
- For rewrites, use `partitionAuthkitHeaders()` and `applyResponseHeaders()` (see README)

**Critical:** Always return via `handleAuthkitHeaders()` to ensure `withAuth()` works in pages.

## Step 5: Create Callback Route

Parse `NEXT_PUBLIC_WORKOS_REDIRECT_URI` to determine route path:
Expand All @@ -78,33 +117,57 @@ export const GET = handleAuth();

Check README for exact usage. If build fails with "cookies outside request scope", the handler is likely missing async/await.

## Step 6: Provider Setup
## Step 6: Provider Setup (REQUIRED)

**CRITICAL:** You MUST wrap the app in `AuthKitProvider` in `app/layout.tsx`.

This is required for:
- Client-side auth state via `useAuth()` hook
- Consistent auth UX across client/server boundaries
- Proper migration from Auth0 (which uses client-side auth)

```tsx
// app/layout.tsx
import { AuthKitProvider } from '@workos-inc/authkit-nextjs';

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<AuthKitProvider>{children}</AuthKitProvider>
</body>
</html>
);
}
```

Check README for exact import path - it may be a subpath export like `@workos-inc/authkit-nextjs/components`.

Wrap app in `AuthKitProvider` in `app/layout.tsx`. See README for import path.
**Do NOT skip this step** even if using server-side auth patterns elsewhere.

## Step 7: UI Integration

Add auth UI to `app/page.tsx` using SDK functions. See README for `getUser`, `getSignInUrl`, `signOut` usage.

## Verification Checklist
## Verification Checklist (ALL MUST PASS)

Run these commands to confirm integration:
Run these commands to confirm integration. **Do not mark complete until all pass:**

```bash
# Check middleware/proxy exists (one should match)
# 1. Check middleware/proxy exists (one should match)
ls proxy.ts middleware.ts src/proxy.ts src/middleware.ts 2>/dev/null

# Check provider is wrapped
grep -l "AuthKitProvider" app/layout.tsx
# 2. CRITICAL: Check AuthKitProvider is in layout (REQUIRED)
grep "AuthKitProvider" app/layout.tsx || echo "FAIL: AuthKitProvider missing from layout"

# Check callback route exists
# 3. Check callback route exists
find app -name "route.ts" -path "*/callback/*"

# Build succeeds
# 4. Build succeeds
npm run build
```

All checks must pass before marking complete.
**If check #2 fails:** Go back to Step 6 and add AuthKitProvider. This is not optional.

## Error Recovery

Expand Down
8 changes: 8 additions & 0 deletions skills/workos-authkit-tanstack-start/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ From README, extract:
## Directory Structure Detection

**Modern TanStack Start (v1.132+)** uses `src/`:

```
src/
├── start.ts # Middleware config (CRITICAL)
Expand All @@ -54,6 +55,7 @@ src/
```

**Legacy (vinxi-based)** uses `app/`:

```
app/
├── start.ts or router.tsx
Expand All @@ -62,6 +64,7 @@ app/
```

**Detection:**

```bash
ls src/routes 2>/dev/null && echo "Modern (src/)" || echo "Legacy (app/)"
```
Expand Down Expand Up @@ -94,6 +97,7 @@ export default {
```

Alternative pattern with createStart:

```typescript
import { createStart } from '@tanstack/react-start';
import { authkitMiddleware } from '@workos/authkit-tanstack-react-start';
Expand Down Expand Up @@ -132,6 +136,7 @@ export const Route = createFileRoute('/api/auth/callback')({
```

**Key points:**

- Use `handleCallbackRoute()` - do not write custom OAuth logic
- Route path string must match the URI path exactly
- This is a server-only route (no component needed)
Expand Down Expand Up @@ -221,6 +226,7 @@ function Profile() {

**Cause:** Route file path doesn't match WORKOS_REDIRECT_URI
**Fix:**

- URI `/api/auth/callback` → file `src/routes/api.auth.callback.tsx` (flat) or `app/routes/api/auth/callback.tsx` (nested)
- Route path string in `createFileRoute()` must match exactly

Expand All @@ -242,6 +248,7 @@ function Profile() {
## SDK Exports Reference

**Server (main export):**

- `authkitMiddleware()` - Request middleware
- `handleCallbackRoute()` - OAuth callback handler
- `getAuth()` - Get current session
Expand All @@ -250,6 +257,7 @@ function Profile() {
- `switchToOrganization()` - Change org context

**Client (`/client` subpath):**

- `AuthKitProvider` - Context provider
- `useAuth()` - Auth state hook
- `useAccessToken()` - Token management
Loading