Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 1 addition & 1 deletion plugins/workos/skills/workos/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: workos
description: Identify which WorkOS reference to load based on the user's task — covers AuthKit, backend SDKs, SSO, RBAC, migrations, management, and all API references.
description: Use when the user is implementing, debugging, or asking about WorkOS in any way — authentication, login, sign-up, sessions, access tokens, organization-scoped tokens, device authorization, SSO, SAML, SCIM, Directory Sync, RBAC, roles, permissions, FGA, MFA, Vault, Audit Logs, Admin Portal, webhooks, events, user management, email, custom domains, AuthKit (any framework), backend SDKs, migrations from Auth0/Clerk/Cognito/Firebase/Supabase/Stytch, or WorkOS API references. Routes to the right reference and gotchas.
---

# WorkOS Skill Router
Expand Down
26 changes: 26 additions & 0 deletions plugins/workos/skills/workos/references/workos-authkit-nextjs.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,23 @@ export default function RootLayout({ children }: { children: React.ReactNode })

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

**IMPORTANT: Server Component Cookie Safety (Next.js 15+/16)**

`getSignInUrl()` internally sets a PKCE cookie via `cookies()`. In Next.js 15+, `cookies()` can only be called in:
- Route Handlers
- Server Actions
- Middleware/Proxy

It **cannot** be called in a Server Component (like `app/page.tsx`). If you call `getSignInUrl()` directly in a page component, you'll get:
> "Cookies can only be modified in a Server Action or Route Handler"

**Correct patterns:**
1. Use `getSignInUrl()` in a Server Action, then pass the URL to the page
2. Use a simple link to `/auth/callback` or the AuthKit-managed sign-in endpoint
3. Use `withAuth()` / `getUser()` for checking auth state (read-only, safe in Server Components)

See README for the recommended approach for your SDK version.

**Note:** The SDK renamed `getUser` to `withAuth` in newer versions. Use whichever function the installed SDK version exports — do NOT rename existing working imports.

## Verification Checklist (ALL MUST PASS)
Expand Down Expand Up @@ -199,6 +216,15 @@ Fix for callback route:

This error causes OAuth codes to expire ("invalid_grant"), so fix the handler first.

### "Cookies can only be modified in a Server Action or Route Handler"

**Cause:** `getSignInUrl()` or `getSignUpUrl()` called directly in a Server Component. These functions set a PKCE cookie internally and must run in a Server Action or Route Handler.

**Fix:**
1. Move the `getSignInUrl()` call to a Server Action
2. Or create a Route Handler that redirects to the sign-in URL
3. Do NOT call `getSignInUrl()` at the top level of a page component

### "middleware.ts not found"

- Check: File at project root or `src/`, not inside `app/`
Expand Down