chub-dev 0.1.0 → 0.1.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +55 -0
  2. package/bin/chub-mcp +2 -0
  3. package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
  4. package/dist/airtable/docs/database/python/DOC.md +1735 -0
  5. package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
  6. package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
  7. package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
  8. package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
  9. package/dist/asana/docs/tasks/DOC.md +1396 -0
  10. package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
  11. package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
  12. package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
  13. package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
  14. package/dist/auth0/docs/identity/python/DOC.md +1199 -0
  15. package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
  16. package/dist/aws/docs/s3/python/DOC.md +1807 -0
  17. package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
  18. package/dist/binance/docs/trading/python/DOC.md +1454 -0
  19. package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
  20. package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
  21. package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
  22. package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
  23. package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
  24. package/dist/clerk/docs/auth/python/DOC.md +274 -0
  25. package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
  26. package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
  27. package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
  28. package/dist/cohere/docs/llm/DOC.md +1335 -0
  29. package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
  30. package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
  31. package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
  32. package/dist/deepgram/docs/speech/python/DOC.md +685 -0
  33. package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
  34. package/dist/deepl/docs/translation/python/DOC.md +944 -0
  35. package/dist/deepseek/docs/llm/DOC.md +1220 -0
  36. package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
  37. package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
  38. package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
  39. package/dist/discord/docs/bot/python/DOC.md +1130 -0
  40. package/dist/elasticsearch/docs/search/DOC.md +1634 -0
  41. package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
  42. package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
  43. package/dist/firebase/docs/auth/DOC.md +1015 -0
  44. package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
  45. package/dist/gemini/docs/genai/python/DOC.md +555 -0
  46. package/dist/github/docs/octokit/DOC.md +1560 -0
  47. package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
  48. package/dist/google/docs/bigquery/python/DOC.md +1503 -0
  49. package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
  50. package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
  51. package/dist/huggingface/docs/transformers/DOC.md +948 -0
  52. package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
  53. package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
  54. package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
  55. package/dist/jira/docs/issues/python/DOC.md +1492 -0
  56. package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
  57. package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
  58. package/dist/landingai-ade/docs/api/DOC.md +620 -0
  59. package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
  60. package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
  61. package/dist/landingai-ade/skills/SKILL.md +489 -0
  62. package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
  63. package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
  64. package/dist/linear/docs/tracker/DOC.md +1554 -0
  65. package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
  66. package/dist/livekit/docs/realtime/python/DOC.md +163 -0
  67. package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
  68. package/dist/meilisearch/docs/search/DOC.md +1241 -0
  69. package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
  70. package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
  71. package/dist/mongodb/docs/atlas/DOC.md +2041 -0
  72. package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
  73. package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
  74. package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
  75. package/dist/okta/docs/identity/python/DOC.md +1401 -0
  76. package/dist/openai/docs/chat/javascript/DOC.md +407 -0
  77. package/dist/openai/docs/chat/python/DOC.md +568 -0
  78. package/dist/paypal/docs/checkout/DOC.md +278 -0
  79. package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
  80. package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
  81. package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
  82. package/dist/plaid/docs/banking/python/DOC.md +1203 -0
  83. package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
  84. package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
  85. package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
  86. package/dist/prisma/docs/orm/python/DOC.md +1317 -0
  87. package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
  88. package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
  89. package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
  90. package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
  91. package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
  92. package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
  93. package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
  94. package/dist/redis/docs/key-value/python/DOC.md +2054 -0
  95. package/dist/registry.json +2817 -0
  96. package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
  97. package/dist/resend/docs/email/DOC.md +1271 -0
  98. package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
  99. package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
  100. package/dist/search-index.json +1 -0
  101. package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
  102. package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
  103. package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
  104. package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
  105. package/dist/shopify/docs/storefront/DOC.md +457 -0
  106. package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
  107. package/dist/slack/docs/workspace/python/DOC.md +271 -0
  108. package/dist/square/docs/payments/javascript/DOC.md +1855 -0
  109. package/dist/square/docs/payments/python/DOC.md +1728 -0
  110. package/dist/stripe/docs/api/DOC.md +1727 -0
  111. package/dist/stripe/docs/payments/DOC.md +1726 -0
  112. package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
  113. package/dist/stytch/docs/auth/python/DOC.md +1962 -0
  114. package/dist/supabase/docs/client/DOC.md +1606 -0
  115. package/dist/twilio/docs/messaging/python/DOC.md +469 -0
  116. package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
  117. package/dist/vercel/docs/platform/DOC.md +1940 -0
  118. package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
  119. package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
  120. package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
  121. package/dist/zendesk/docs/support/python/DOC.md +2297 -0
  122. package/package.json +22 -6
  123. package/skills/get-api-docs/SKILL.md +84 -0
  124. package/src/commands/annotate.js +83 -0
  125. package/src/commands/build.js +12 -1
  126. package/src/commands/feedback.js +150 -0
  127. package/src/commands/get.js +83 -42
  128. package/src/commands/search.js +7 -0
  129. package/src/index.js +43 -17
  130. package/src/lib/analytics.js +90 -0
  131. package/src/lib/annotations.js +57 -0
  132. package/src/lib/bm25.js +170 -0
  133. package/src/lib/cache.js +69 -6
  134. package/src/lib/config.js +8 -3
  135. package/src/lib/identity.js +99 -0
  136. package/src/lib/registry.js +103 -20
  137. package/src/lib/telemetry.js +86 -0
  138. package/src/mcp/server.js +177 -0
  139. package/src/mcp/tools.js +251 -0
@@ -0,0 +1,1220 @@
1
+ ---
2
+ name: auth
3
+ description: "Clerk JavaScript SDK for user authentication, session management, and identity workflows"
4
+ metadata:
5
+ languages: "javascript"
6
+ versions: "5.1.6"
7
+ updated-on: "2026-03-01"
8
+ source: maintainer
9
+ tags: "clerk,auth,authentication,user-management,session"
10
+ ---
11
+
12
+ # Clerk JavaScript SDK Coding Guidelines
13
+
14
+ You are a Clerk authentication expert. Help me with writing code using the Clerk JavaScript SDK and its official libraries for user authentication and management.
15
+
16
+ This guide covers both vanilla JavaScript implementations using `@clerk/clerk-js` and framework-specific implementations using packages like `@clerk/nextjs` and `@clerk/react`.
17
+
18
+ Please follow the following guidelines when generating code.
19
+
20
+ You can find the official documentation and code samples here:
21
+ https://clerk.com/docs
22
+
23
+ ## Important Context About This SDK
24
+
25
+ Clerk provides **two main approaches** for JavaScript authentication:
26
+ 1. **Vanilla JavaScript (`@clerk/clerk-js`)**: Uses the browser SDK loaded via CDN or NPM, ideal for standalone HTML/JS apps
27
+ 2. **Framework SDKs**: Specialized packages for Next.js, React, Vue, etc. with framework-specific optimizations
28
+
29
+ This context guide covers both approaches comprehensively.
30
+
31
+ ## Golden Rule: Use the Correct Clerk Package for Your Framework
32
+
33
+ Always use the appropriate Clerk SDK for your specific framework or environment. Clerk provides specialized packages for different platforms that include framework-specific optimizations and integrations.
34
+
35
+ **Available Packages:**
36
+ - **Next.js:** `@clerk/nextjs`
37
+ - **React:** `@clerk/react`
38
+ - **Vanilla JavaScript:** `@clerk/clerk-js`
39
+ - **Vue:** `@clerk/vue`
40
+ - **Astro:** `@clerk/astro`
41
+ - **Remix:** `@clerk/remix`
42
+ - **Express:** `@clerk/express`
43
+ - **Fastify:** `@clerk/fastify`
44
+ - **Expo:** `@clerk/expo`
45
+
46
+ **Installation Examples:**
47
+ ```bash
48
+ # For Next.js applications
49
+ npm install @clerk/nextjs
50
+
51
+ # For React applications
52
+ npm install @clerk/react
53
+
54
+ # For vanilla JavaScript
55
+ npm install @clerk/clerk-js
56
+ ```
57
+
58
+ ## Prerequisites and Setup
59
+
60
+ - An existing Clerk application from the [Clerk Dashboard](https://dashboard.clerk.com/sign-up)
61
+ - For Next.js: Next.js 13.0.4 or later, React 18 or later, Node.js >=18.17.0
62
+ - For vanilla JavaScript: Any modern browser with ES6+ support
63
+
64
+ ## Environment Variables
65
+
66
+ ### For Framework Apps (Next.js, React, etc.)
67
+ Set up your environment variables in `.env.local`:
68
+ ```
69
+ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
70
+ CLERK_SECRET_KEY=sk_test_...
71
+ ```
72
+
73
+ ### For Vanilla JavaScript Apps
74
+ Store your publishable key in a `.env` file and inject it into your HTML:
75
+ ```
76
+ CLERK_PUBLISHABLE_KEY=pk_test_...
77
+ ```
78
+
79
+ **Important**: Only the publishable key is needed for client-side authentication. Never expose your secret key in browser code.
80
+
81
+ ## Next.js Integration
82
+
83
+ ### ClerkProvider Setup
84
+
85
+ Wrap your application with ClerkProvider:
86
+
87
+ ```jsx
88
+ import { ClerkProvider } from '@clerk/nextjs'
89
+
90
+ export default function RootLayout({ children }) {
91
+ return (
92
+ <ClerkProvider>
93
+ <html lang="en">
94
+ <body>{children}</body>
95
+ </html>
96
+ </ClerkProvider>
97
+ )
98
+ }
99
+ ```
100
+
101
+ ### Middleware Configuration
102
+
103
+ Use `clerkMiddleware` for route protection:
104
+
105
+ ```javascript
106
+ import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
107
+
108
+ const isProtectedRoute = createRouteMatcher(['/protected(.*)']);
109
+ const isAdminRoute = createRouteMatcher(['/admin(.*)']);
110
+
111
+ export default clerkMiddleware(async (auth, req) => {
112
+ if (isProtectedRoute(req)) {
113
+ await auth.protect();
114
+ }
115
+
116
+ if (isAdminRoute(req)) {
117
+ await auth.protect({ role: 'org:admin' });
118
+ }
119
+ });
120
+ ```
121
+
122
+ **Important:** Do not use the deprecated `authMiddleware`. Always use `clerkMiddleware` for new implementations.
123
+
124
+ ## Client-Side Authentication Hooks
125
+
126
+ ### useUser Hook
127
+
128
+ Access the current user information:
129
+
130
+ ```jsx
131
+ import { useUser } from '@clerk/nextjs';
132
+
133
+ function UserProfile() {
134
+ const { isLoaded, isSignedIn, user } = useUser();
135
+
136
+ if (!isLoaded || !isSignedIn) {
137
+ return null;
138
+ }
139
+
140
+ return <div>Hello, {user.firstName}!</div>;
141
+ }
142
+ ```
143
+
144
+ ### useAuth Hook
145
+
146
+ Access authentication state and methods:
147
+
148
+ ```jsx
149
+ import { useAuth } from '@clerk/nextjs';
150
+
151
+ function AuthComponent() {
152
+ const { isLoaded, userId, sessionId, getToken } = useAuth();
153
+
154
+ // Use authentication state
155
+ }
156
+ ```
157
+
158
+ ### useClerk Hook
159
+
160
+ Access the Clerk instance for advanced operations:
161
+
162
+ ```jsx
163
+ import { useClerk } from '@clerk/nextjs';
164
+
165
+ function SignOutButton() {
166
+ const { signOut } = useClerk();
167
+
168
+ return <button onClick={() => signOut()}>Sign out</button>;
169
+ }
170
+ ```
171
+
172
+ ## Server-Side Authentication
173
+
174
+ ### auth() Helper (App Router)
175
+
176
+ Use the `auth()` helper in Server Components, Route Handlers, and Server Actions:
177
+
178
+ ```jsx
179
+ import { auth } from '@clerk/nextjs/server';
180
+
181
+ export default async function Page() {
182
+ const { userId } = await auth();
183
+
184
+ if (!userId) {
185
+ return <div>Please sign in</div>;
186
+ }
187
+
188
+ return <div>User ID: {userId}</div>;
189
+ }
190
+ ```
191
+
192
+ ### currentUser() Helper
193
+
194
+ Get the full user object on the server side:
195
+
196
+ ```jsx
197
+ import { currentUser } from '@clerk/nextjs/server';
198
+
199
+ export default async function Page() {
200
+ const user = await currentUser();
201
+
202
+ if (!user) return <div>Not signed in</div>;
203
+
204
+ return <div>Hello {user?.firstName}</div>;
205
+ }
206
+ ```
207
+
208
+ ### auth.protect() Method
209
+
210
+ Use `auth.protect()` for authentication and authorization checks:
211
+
212
+ ```jsx
213
+ import { auth } from '@clerk/nextjs/server';
214
+
215
+ export default async function AdminPage() {
216
+ // Protect route - redirects unauthenticated users
217
+ await auth.protect();
218
+
219
+ // Or protect with role check
220
+ await auth.protect({ role: 'org:admin' });
221
+
222
+ return <div>Protected content</div>;
223
+ }
224
+ ```
225
+
226
+ ## Authentication Components
227
+
228
+ ### Sign-In and Sign-Up Buttons
229
+
230
+ Use pre-built buttons for authentication flows:
231
+
232
+ ```jsx
233
+ import { SignInButton, SignUpButton } from '@clerk/nextjs';
234
+
235
+ export default function Home() {
236
+ return (
237
+ <main>
238
+ <SignInButton mode='modal' forceRedirectUrl='/protected'>
239
+ Sign in button
240
+ </SignInButton>
241
+
242
+ <SignUpButton mode='modal' forceRedirectUrl='/protected'>
243
+ Sign up button
244
+ </SignUpButton>
245
+ </main>
246
+ );
247
+ }
248
+ ```
249
+
250
+ ### Pre-built Components
251
+
252
+ ```jsx
253
+ import {
254
+ SignIn,
255
+ SignUp,
256
+ UserButton,
257
+ UserProfile
258
+ } from '@clerk/nextjs';
259
+
260
+ // Drop-in authentication components
261
+ <SignIn />
262
+ <SignUp />
263
+ <UserButton />
264
+ <UserProfile />
265
+ ```
266
+
267
+ ## Organization Management
268
+
269
+ ### Organization Roles and Permissions
270
+
271
+ Clerk supports role-based access control within organizations:
272
+
273
+ ```jsx
274
+ // Check organization permissions
275
+ await auth.protect({
276
+ role: 'org:admin'
277
+ });
278
+
279
+ // Custom permissions
280
+ await auth.protect({
281
+ permission: 'org:sys_memberships:manage'
282
+ });
283
+ ```
284
+
285
+ ### Organization Hooks
286
+
287
+ ```jsx
288
+ import {
289
+ useOrganization,
290
+ useOrganizationList,
291
+ useUser
292
+ } from '@clerk/nextjs';
293
+
294
+ function OrganizationComponent() {
295
+ const { organization } = useOrganization();
296
+ const { organizationList } = useOrganizationList();
297
+
298
+ // Organization management logic
299
+ }
300
+ ```
301
+
302
+ ## Common Patterns
303
+
304
+ ### Conditional Rendering Based on Auth State
305
+
306
+ ```jsx
307
+ import { useUser } from '@clerk/nextjs';
308
+
309
+ function App() {
310
+ const { isSignedIn } = useUser();
311
+
312
+ return (
313
+ <div>
314
+ {isSignedIn ? (
315
+ <AuthenticatedApp />
316
+ ) : (
317
+ <UnauthenticatedApp />
318
+ )}
319
+ </div>
320
+ );
321
+ }
322
+ ```
323
+
324
+ ### Route Protection with Redirects
325
+
326
+ ```jsx
327
+ import { auth } from '@clerk/nextjs/server';
328
+
329
+ export default async function ProtectedPage() {
330
+ const { userId } = await auth();
331
+
332
+ if (!userId) {
333
+ redirect('/sign-in');
334
+ }
335
+
336
+ return <div>Protected content</div>;
337
+ }
338
+ ```
339
+
340
+ ## Vanilla JavaScript Integration (`@clerk/clerk-js`)
341
+
342
+ ### Loading Clerk via CDN
343
+
344
+ The most common approach for vanilla JavaScript apps is loading Clerk from a CDN:
345
+
346
+ ```html
347
+ <!DOCTYPE html>
348
+ <html>
349
+ <head>
350
+ <title>My App</title>
351
+ </head>
352
+ <body>
353
+ <!-- Your content here -->
354
+
355
+ <!-- Load Clerk SDK -->
356
+ <script
357
+ async
358
+ crossorigin="anonymous"
359
+ data-clerk-publishable-key="pk_test_..."
360
+ src="https://[your-clerk-domain].clerk.accounts.dev/npm/@clerk/clerk-js@latest/dist/clerk.browser.js"
361
+ type="text/javascript"
362
+ ></script>
363
+
364
+ <script src="app.js"></script>
365
+ </body>
366
+ </html>
367
+ ```
368
+
369
+ **Important Implementation Details:**
370
+ - The Clerk SDK loads **asynchronously**, so you must wait for it to be ready
371
+ - Access the Clerk instance via `window.Clerk`
372
+ - Always call `await clerk.load()` before using any Clerk methods
373
+ - Listen for the `clerk:loaded` event as a fallback if the script hasn't loaded yet
374
+
375
+ ### Initializing Clerk Properly
376
+
377
+ ```javascript
378
+ // Wait for page to load
379
+ window.addEventListener('load', async () => {
380
+ if (window.Clerk) {
381
+ // Clerk is already available
382
+ await initializeClerk(window.Clerk);
383
+ } else {
384
+ // Wait for Clerk to load
385
+ window.addEventListener('clerk:loaded', async (event) => {
386
+ await initializeClerk(event.detail);
387
+ });
388
+ }
389
+ });
390
+
391
+ async function initializeClerk(clerk) {
392
+ try {
393
+ // CRITICAL: Always call load() first
394
+ await clerk.load();
395
+
396
+ // Now you can safely use clerk methods
397
+ const user = clerk.user;
398
+
399
+ // Your authentication logic here
400
+ } catch (error) {
401
+ console.error('Error initializing Clerk:', error);
402
+ }
403
+ }
404
+ ```
405
+
406
+ ### Accessing User Information
407
+
408
+ After Clerk is loaded, access the current user via `clerk.user`:
409
+
410
+ ```javascript
411
+ async function initializeClerk(clerk) {
412
+ await clerk.load();
413
+
414
+ const user = clerk.user;
415
+
416
+ if (user) {
417
+ // User is authenticated
418
+ console.log('User ID:', user.id);
419
+ console.log('Name:', user.firstName, user.lastName);
420
+ console.log('Email:', user.primaryEmailAddress?.emailAddress);
421
+ console.log('Created:', new Date(user.createdAt));
422
+
423
+ // Access other user properties
424
+ console.log('Phone:', user.primaryPhoneNumber?.phoneNumber);
425
+ console.log('Profile Image:', user.imageUrl);
426
+ } else {
427
+ // User is not signed in
428
+ console.log('No user signed in');
429
+ }
430
+ }
431
+ ```
432
+
433
+ ### Mounting Authentication Components
434
+
435
+ Clerk provides pre-built UI components that can be mounted into your HTML:
436
+
437
+ ```javascript
438
+ async function initializeClerk(clerk) {
439
+ await clerk.load();
440
+
441
+ if (!clerk.user) {
442
+ // Mount sign-in component for unauthenticated users
443
+ clerk.mountSignIn(document.getElementById('sign-in-container'));
444
+ } else {
445
+ // Mount user button for authenticated users
446
+ clerk.mountUserButton(document.getElementById('user-button-container'));
447
+ }
448
+ }
449
+ ```
450
+
451
+ **Available mount methods:**
452
+ - `clerk.mountSignIn(element)` - Full sign-in flow
453
+ - `clerk.mountSignUp(element)` - Full sign-up flow
454
+ - `clerk.mountUserButton(element)` - User profile dropdown button
455
+ - `clerk.mountUserProfile(element)` - Complete user profile management
456
+
457
+ ### Listening to Authentication State Changes
458
+
459
+ Use `clerk.addListener()` to react to authentication changes:
460
+
461
+ ```javascript
462
+ async function initializeClerk(clerk) {
463
+ await clerk.load();
464
+
465
+ // Initial UI update
466
+ updateUI(clerk.user);
467
+
468
+ // Listen for changes
469
+ clerk.addListener((emission) => {
470
+ // The emission object contains the changed properties
471
+ if (emission.user !== undefined) {
472
+ // User state changed (sign in, sign out, or profile update)
473
+ updateUI(emission.user);
474
+ }
475
+
476
+ if (emission.session !== undefined) {
477
+ // Session changed
478
+ console.log('Session updated:', emission.session);
479
+ }
480
+
481
+ if (emission.organization !== undefined) {
482
+ // Organization changed
483
+ console.log('Organization updated:', emission.organization);
484
+ }
485
+ });
486
+ }
487
+
488
+ function updateUI(user) {
489
+ const authenticatedView = document.getElementById('authenticated-view');
490
+ const unauthenticatedView = document.getElementById('unauthenticated-view');
491
+
492
+ if (user) {
493
+ unauthenticatedView.classList.add('hidden');
494
+ authenticatedView.classList.remove('hidden');
495
+ } else {
496
+ authenticatedView.classList.add('hidden');
497
+ unauthenticatedView.classList.remove('hidden');
498
+ }
499
+ }
500
+ ```
501
+
502
+ ### Implementing Sign Out
503
+
504
+ ```javascript
505
+ async function handleSignOut(clerk) {
506
+ try {
507
+ await clerk.signOut();
508
+ // UI will update automatically via listener
509
+ console.log('Signed out successfully');
510
+ } catch (error) {
511
+ console.error('Sign out failed:', error);
512
+ }
513
+ }
514
+
515
+ // Usage in your HTML
516
+ document.getElementById('sign-out-btn').addEventListener('click', () => {
517
+ handleSignOut(window.Clerk);
518
+ });
519
+ ```
520
+
521
+ ### Complete Vanilla JavaScript Example
522
+
523
+ Here's a complete working example:
524
+
525
+ ```javascript
526
+ // app.js
527
+ window.addEventListener('load', async () => {
528
+ if (window.Clerk) {
529
+ await initializeClerk(window.Clerk);
530
+ } else {
531
+ window.addEventListener('clerk:loaded', async (event) => {
532
+ await initializeClerk(event.detail);
533
+ });
534
+ }
535
+ });
536
+
537
+ async function initializeClerk(clerk) {
538
+ try {
539
+ await clerk.load();
540
+
541
+ const loadingView = document.getElementById('loading-view');
542
+ const authenticatedView = document.getElementById('authenticated-view');
543
+ const unauthenticatedView = document.getElementById('unauthenticated-view');
544
+ const userInfo = document.getElementById('user-info');
545
+ const signOutBtn = document.getElementById('sign-out-btn');
546
+
547
+ function updateUI() {
548
+ const user = clerk.user;
549
+ loadingView.classList.add('hidden');
550
+
551
+ if (user) {
552
+ unauthenticatedView.classList.add('hidden');
553
+ authenticatedView.classList.remove('hidden');
554
+
555
+ userInfo.innerHTML = `
556
+ <h3>User Information</h3>
557
+ <p><strong>Name:</strong> ${user.firstName || ''} ${user.lastName || ''}</p>
558
+ <p><strong>Email:</strong> ${user.primaryEmailAddress?.emailAddress || 'N/A'}</p>
559
+ <p><strong>User ID:</strong> ${user.id}</p>
560
+ <p><strong>Created:</strong> ${new Date(user.createdAt).toLocaleDateString()}</p>
561
+ `;
562
+ } else {
563
+ authenticatedView.classList.add('hidden');
564
+ unauthenticatedView.classList.remove('hidden');
565
+ clerk.mountSignIn(document.getElementById('clerk-sign-in'));
566
+ }
567
+ }
568
+
569
+ updateUI();
570
+
571
+ clerk.addListener((emission) => {
572
+ if (emission.user !== undefined) {
573
+ updateUI();
574
+ }
575
+ });
576
+
577
+ signOutBtn.addEventListener('click', async () => {
578
+ await clerk.signOut();
579
+ updateUI();
580
+ });
581
+
582
+ clerk.mountUserButton(document.getElementById('clerk-user-button'));
583
+
584
+ } catch (error) {
585
+ console.error('Error initializing Clerk:', error);
586
+ }
587
+ }
588
+ ```
589
+
590
+ ### Server-Side Key Injection Pattern
591
+
592
+ For production apps, inject the publishable key server-side to keep it out of version control:
593
+
594
+ ```javascript
595
+ // server.js (Node.js example)
596
+ const http = require('http');
597
+ const fs = require('fs');
598
+ require('dotenv').config();
599
+
600
+ const server = http.createServer((req, res) => {
601
+ if (req.url === '/' || req.url === '/index.html') {
602
+ let html = fs.readFileSync('./index.html', 'utf-8');
603
+
604
+ // Replace placeholder with actual key
605
+ html = html.replace(
606
+ 'CLERK_PUBLISHABLE_KEY_PLACEHOLDER',
607
+ process.env.CLERK_PUBLISHABLE_KEY
608
+ );
609
+
610
+ res.writeHead(200, { 'Content-Type': 'text/html' });
611
+ res.end(html);
612
+ }
613
+ });
614
+
615
+ server.listen(3000);
616
+ ```
617
+
618
+ ```html
619
+ <!-- index.html -->
620
+ <script
621
+ data-clerk-publishable-key="CLERK_PUBLISHABLE_KEY_PLACEHOLDER"
622
+ src="https://[your-domain].clerk.accounts.dev/npm/@clerk/clerk-js@latest/dist/clerk.browser.js"
623
+ ></script>
624
+ ```
625
+
626
+ ### Getting Authentication Tokens for API Calls
627
+
628
+ ```javascript
629
+ async function makeAuthenticatedRequest(clerk) {
630
+ try {
631
+ // Get the current session token
632
+ const token = await clerk.session.getToken();
633
+
634
+ const response = await fetch('/api/protected-endpoint', {
635
+ headers: {
636
+ 'Authorization': `Bearer ${token}`,
637
+ 'Content-Type': 'application/json'
638
+ }
639
+ });
640
+
641
+ const data = await response.json();
642
+ return data;
643
+ } catch (error) {
644
+ console.error('API request failed:', error);
645
+ }
646
+ }
647
+ ```
648
+
649
+ ### Handling Session Lifecycle
650
+
651
+ ```javascript
652
+ async function initializeClerk(clerk) {
653
+ await clerk.load();
654
+
655
+ // Check if session exists
656
+ if (clerk.session) {
657
+ console.log('Active session:', clerk.session.id);
658
+ console.log('Session expires:', new Date(clerk.session.expireAt));
659
+
660
+ // Get session token
661
+ const token = await clerk.session.getToken();
662
+ console.log('Session token:', token);
663
+ }
664
+
665
+ // Listen for session changes
666
+ clerk.addListener((emission) => {
667
+ if (emission.session !== undefined) {
668
+ if (emission.session) {
669
+ console.log('New session created');
670
+ } else {
671
+ console.log('Session ended');
672
+ }
673
+ }
674
+ });
675
+ }
676
+ ```
677
+
678
+ ## API Endpoints and Backend Integration
679
+
680
+ ### Backend Package
681
+
682
+ For backend-only applications, use `@clerk/backend`:
683
+
684
+ ```javascript
685
+ import { clerkClient } from '@clerk/backend';
686
+
687
+ // Server-side user management
688
+ const user = await clerkClient.users.getUser(userId);
689
+ ```
690
+
691
+ ### Verifying Tokens on Your Backend
692
+
693
+ ```javascript
694
+ // Node.js/Express example
695
+ const { verifyToken } = require('@clerk/backend');
696
+
697
+ app.get('/api/protected', async (req, res) => {
698
+ try {
699
+ const token = req.headers.authorization?.replace('Bearer ', '');
700
+ const claims = await verifyToken(token, {
701
+ secretKey: process.env.CLERK_SECRET_KEY
702
+ });
703
+
704
+ // Token is valid, proceed with request
705
+ res.json({ userId: claims.sub });
706
+ } catch (error) {
707
+ res.status(401).json({ error: 'Unauthorized' });
708
+ }
709
+ });
710
+ ```
711
+
712
+ ## Common Pitfalls and Best Practices
713
+
714
+ ### Vanilla JavaScript Pitfalls
715
+
716
+ **Pitfall 1: Not waiting for Clerk to load**
717
+ ```javascript
718
+ // WRONG - Clerk may not be loaded yet
719
+ window.Clerk.user; // May be undefined
720
+
721
+ // CORRECT - Wait for load event
722
+ window.addEventListener('load', async () => {
723
+ if (window.Clerk) {
724
+ await window.Clerk.load();
725
+ const user = window.Clerk.user; // Now safe to use
726
+ }
727
+ });
728
+ ```
729
+
730
+ **Pitfall 2: Forgetting to call clerk.load()**
731
+ ```javascript
732
+ // WRONG
733
+ async function initializeClerk(clerk) {
734
+ const user = clerk.user; // May not be initialized yet
735
+ }
736
+
737
+ // CORRECT
738
+ async function initializeClerk(clerk) {
739
+ await clerk.load(); // CRITICAL - must call first
740
+ const user = clerk.user;
741
+ }
742
+ ```
743
+
744
+ **Pitfall 3: Not handling both load scenarios**
745
+ ```javascript
746
+ // INCOMPLETE - only handles one scenario
747
+ window.addEventListener('load', async () => {
748
+ await initializeClerk(window.Clerk); // What if Clerk isn't loaded yet?
749
+ });
750
+
751
+ // COMPLETE - handles both scenarios
752
+ window.addEventListener('load', async () => {
753
+ if (window.Clerk) {
754
+ await initializeClerk(window.Clerk);
755
+ } else {
756
+ window.addEventListener('clerk:loaded', async (event) => {
757
+ await initializeClerk(event.detail);
758
+ });
759
+ }
760
+ });
761
+ ```
762
+
763
+ ### Framework Best Practices
764
+
765
+ **Use loading states properly:**
766
+ ```javascript
767
+ const { isLoaded, isSignedIn, user } = useUser();
768
+
769
+ // Always check isLoaded first
770
+ if (!isLoaded) {
771
+ return <LoadingSpinner />;
772
+ }
773
+
774
+ if (!isSignedIn) {
775
+ return <SignInPrompt />;
776
+ }
777
+
778
+ // Now safe to use user
779
+ return <UserProfile user={user} />;
780
+ ```
781
+
782
+ **Avoid conditional hooks:**
783
+ ```javascript
784
+ // WRONG
785
+ if (someCondition) {
786
+ const { user } = useUser(); // Breaks rules of hooks
787
+ }
788
+
789
+ // CORRECT
790
+ const { user } = useUser();
791
+ if (someCondition && user) {
792
+ // Use user here
793
+ }
794
+ ```
795
+
796
+ ### Security Best Practices
797
+
798
+ 1. **Never expose secret keys** - Only use publishable keys in client-side code
799
+ 2. **Verify tokens on the backend** - Don't trust client-side authentication alone
800
+ 3. **Use HTTPS** - Always serve your app over HTTPS in production
801
+ 4. **Implement CORS properly** - Configure allowed origins in Clerk Dashboard
802
+ 5. **Handle token expiration** - Sessions expire and need refresh
803
+
804
+ ### Performance Optimization
805
+
806
+ **For Next.js:**
807
+ - Use `auth()` instead of `currentUser()` when you only need the user ID
808
+ - `currentUser()` makes an API call while `auth()` reads from the request
809
+ - Implement proper caching strategies for user data
810
+
811
+ **For Vanilla JS:**
812
+ - Load Clerk SDK asynchronously (use `async` attribute)
813
+ - Cache user data in memory to avoid repeated property access
814
+ - Use event listeners instead of polling for auth state changes
815
+
816
+ ## Important Notes
817
+
818
+ ### Framework-Specific Notes
819
+
820
+ - **Next.js Middleware Requirement:** `clerkMiddleware()` is required for server-side authentication helpers in Next.js App Router
821
+ - **Server-Only Functions:** Functions like `auth()` and `currentUser()` only work on the server side
822
+ - **Rate Limits:** Server-side user fetching counts towards Backend API rate limits
823
+ - **Deprecated APIs:** Do not use `authMiddleware` - use `clerkMiddleware` instead
824
+
825
+ ### Vanilla JavaScript Notes
826
+
827
+ - **Asynchronous Loading:** The Clerk SDK loads asynchronously - always wait for it to be ready
828
+ - **Critical Load Step:** Always call `await clerk.load()` before accessing user/session data
829
+ - **Event-Driven Updates:** Use `clerk.addListener()` for reactive UI updates
830
+ - **Session Tokens:** Access tokens via `clerk.session.getToken()` for API authentication
831
+ - **Component Mounting:** Use mount methods (`mountSignIn`, etc.) for pre-built UI components
832
+
833
+ ## Useful Links
834
+
835
+ - **Documentation:** https://clerk.com/docs
836
+ - **Quickstart Guides:** https://clerk.com/docs/quickstarts/overview
837
+ - **Discord Community:** https://clerk.com/discord
838
+ - **GitHub Repository:** https://github.com/clerk/javascript
839
+
840
+ ## Quick Reference: Choosing Your Implementation
841
+
842
+ ### Use Vanilla JavaScript (`@clerk/clerk-js`) when:
843
+ - Building standalone HTML/JS applications
844
+ - Working without a framework
845
+ - Need simple drop-in authentication
846
+ - Want to use CDN-hosted SDK
847
+ - Building static sites with authentication
848
+
849
+ **Key Pattern:**
850
+ ```javascript
851
+ window.addEventListener('load', async () => {
852
+ if (window.Clerk) {
853
+ await window.Clerk.load();
854
+ // Use window.Clerk.user
855
+ }
856
+ });
857
+ ```
858
+
859
+ ### Use Next.js SDK (`@clerk/nextjs`) when:
860
+ - Building Next.js applications (App Router or Pages Router)
861
+ - Need server-side authentication
862
+ - Want middleware-based route protection
863
+ - Building full-stack applications with Next.js
864
+
865
+ **Key Pattern:**
866
+ ```javascript
867
+ // Client: useUser(), useAuth(), useClerk()
868
+ // Server: auth(), currentUser()
869
+ // Middleware: clerkMiddleware()
870
+ ```
871
+
872
+ ### Use React SDK (`@clerk/react`) when:
873
+ - Building React applications (not Next.js)
874
+ - Using Create React App or Vite
875
+ - Need client-side authentication hooks
876
+ - Working with React Router
877
+
878
+ **Key Pattern:**
879
+ ```javascript
880
+ import { ClerkProvider, useUser } from '@clerk/react';
881
+ ```
882
+
883
+ ### Use Backend SDK (`@clerk/backend`) when:
884
+ - Building backend-only APIs
885
+ - Need to verify tokens server-side
886
+ - Managing users from your backend
887
+ - Integrating with Express, Fastify, etc.
888
+
889
+ **Key Pattern:**
890
+ ```javascript
891
+ import { clerkClient, verifyToken } from '@clerk/backend';
892
+ ```
893
+
894
+ ## Summary
895
+
896
+ This guide covers the core Clerk JavaScript SDK patterns across multiple implementation approaches:
897
+
898
+ ### Key Concepts
899
+ - **Clerk is framework-agnostic** - Choose the right package for your stack
900
+ - **Publishable keys are safe for client-side** - Secret keys are for backend only
901
+ - **Authentication is session-based** - Clerk manages sessions automatically
902
+ - **Pre-built components** - Drop-in UI for authentication flows
903
+ - **Event-driven updates** - React to auth state changes in real-time
904
+
905
+ ### Critical Implementation Details
906
+
907
+ **For Vanilla JavaScript:**
908
+ 1. Always wait for Clerk to load (`window.Clerk` + `clerk:loaded` event)
909
+ 2. Call `await clerk.load()` before accessing user/session data
910
+ 3. Use `clerk.addListener()` for reactive UI updates
911
+ 4. Mount components with `clerk.mountSignIn()`, `clerk.mountUserButton()`, etc.
912
+
913
+ **For Next.js:**
914
+ 1. Wrap app with `<ClerkProvider>`
915
+ 2. Use `clerkMiddleware()` for route protection
916
+ 3. Use hooks (`useUser()`, `useAuth()`) in client components
917
+ 4. Use `auth()` and `currentUser()` in server components
918
+
919
+ **For Backend:**
920
+ 1. Verify tokens with `verifyToken()` or middleware
921
+ 2. Use `clerkClient` for user management operations
922
+ 3. Never expose secret keys to the client
923
+
924
+ ### Authentication Flow
925
+ 1. User visits your app
926
+ 2. Clerk SDK initializes and checks for existing session
927
+ 3. If no session, show sign-in UI
928
+ 4. User authenticates (email, OAuth, etc.)
929
+ 5. Clerk creates session and returns user object
930
+ 6. Your app reacts to auth state and shows user content
931
+ 7. Session tokens can be used for API authentication
932
+
933
+ Clerk handles the complexity of authentication, session management, and user profiles, allowing you to focus on building your application.
934
+
935
+ ## Common Use Cases & Patterns
936
+
937
+ ### Protected Routes (Vanilla JS)
938
+ ```javascript
939
+ async function initializeClerk(clerk) {
940
+ await clerk.load();
941
+
942
+ // Protect specific pages
943
+ const protectedPaths = ['/dashboard', '/profile', '/settings'];
944
+ const currentPath = window.location.pathname;
945
+
946
+ if (protectedPaths.includes(currentPath) && !clerk.user) {
947
+ // Redirect to sign-in
948
+ window.location.href = '/sign-in';
949
+ }
950
+ }
951
+ ```
952
+
953
+ ### Protected Routes (Next.js Middleware)
954
+ ```javascript
955
+ import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
956
+
957
+ const isProtectedRoute = createRouteMatcher(['/dashboard(.*)']);
958
+
959
+ export default clerkMiddleware(async (auth, req) => {
960
+ if (isProtectedRoute(req)) {
961
+ await auth.protect(); // Redirects if not authenticated
962
+ }
963
+ });
964
+ ```
965
+
966
+ ### Displaying User-Specific Content
967
+ ```javascript
968
+ // Vanilla JS
969
+ if (clerk.user) {
970
+ document.getElementById('welcome').textContent =
971
+ `Welcome back, ${clerk.user.firstName}!`;
972
+ }
973
+
974
+ // Next.js/React
975
+ const { user } = useUser();
976
+ return user ? <div>Welcome back, {user.firstName}!</div> : null;
977
+ ```
978
+
979
+ ### Making Authenticated API Requests
980
+ ```javascript
981
+ // Vanilla JS
982
+ const token = await clerk.session.getToken();
983
+ const response = await fetch('/api/data', {
984
+ headers: { 'Authorization': `Bearer ${token}` }
985
+ });
986
+
987
+ // Next.js/React
988
+ const { getToken } = useAuth();
989
+ const token = await getToken();
990
+ const response = await fetch('/api/data', {
991
+ headers: { 'Authorization': `Bearer ${token}` }
992
+ });
993
+ ```
994
+
995
+ ### Handling OAuth Sign-In
996
+ ```javascript
997
+ // Clerk handles OAuth automatically through its UI components
998
+ // Just mount the sign-in component and it includes OAuth buttons
999
+
1000
+ // Vanilla JS
1001
+ clerk.mountSignIn(document.getElementById('sign-in'));
1002
+
1003
+ // Next.js/React
1004
+ <SignIn />
1005
+ ```
1006
+
1007
+ ### Custom OAuth Redirect URLs
1008
+ ```jsx
1009
+ <SignInButton
1010
+ mode='modal'
1011
+ forceRedirectUrl='/dashboard'
1012
+ signUpForceRedirectUrl='/onboarding'
1013
+ >
1014
+ Sign in
1015
+ </SignInButton>
1016
+ ```
1017
+
1018
+ ## Troubleshooting Common Issues
1019
+
1020
+ ### Issue: "Clerk is not defined"
1021
+ **Cause:** Clerk SDK hasn't loaded yet
1022
+ **Solution:** Use the proper loading pattern with both `window.Clerk` check and `clerk:loaded` event
1023
+
1024
+ ### Issue: "User is null after sign-in"
1025
+ **Cause:** Forgot to call `clerk.load()` or checking too early
1026
+ **Solution:** Always call `await clerk.load()` and use event listeners for updates
1027
+
1028
+ ### Issue: "Cannot read property 'user' of undefined"
1029
+ **Cause:** Accessing Clerk before initialization
1030
+ **Solution:** Wrap all Clerk usage in the initialization function after `load()` completes
1031
+
1032
+ ### Issue: "CORS errors when calling Clerk API"
1033
+ **Cause:** Domain not configured in Clerk Dashboard
1034
+ **Solution:** Add your domain to allowed origins in Clerk Dashboard settings
1035
+
1036
+ ### Issue: "Session token expired"
1037
+ **Cause:** Sessions expire after period of inactivity
1038
+ **Solution:** Clerk automatically refreshes tokens; ensure you call `getToken()` fresh each time
1039
+
1040
+ ### Issue: "Middleware not protecting routes"
1041
+ **Cause:** Incorrect middleware configuration or matcher pattern
1042
+ **Solution:** Verify `clerkMiddleware` is exported as default and matcher patterns are correct
1043
+
1044
+ ### Issue: "Can't access user data in Server Component"
1045
+ **Cause:** Using client-side hooks on the server
1046
+ **Solution:** Use `auth()` or `currentUser()` instead of `useUser()` in Server Components
1047
+
1048
+ ### Debugging Tips
1049
+
1050
+ 1. **Check Clerk Dashboard:** Verify your API keys are correct
1051
+ 2. **Console logging:** Add `console.log('Clerk loaded:', clerk)` after `load()`
1052
+ 3. **Network tab:** Check for failed requests to Clerk API
1053
+ 4. **Browser console:** Look for Clerk SDK errors or warnings
1054
+ 5. **Version compatibility:** Ensure your Clerk package versions are up to date
1055
+
1056
+ ## Prerequisites
1057
+
1058
+ - Next.js 13.0.4 or later
1059
+ - React 18 or later
1060
+ - Node.js `>=18.17.0` or later
1061
+ - An existing Clerk application. [Create your account for free](https://dashboard.clerk.com/sign-up?utm_source=github&utm_medium=clerk_nextjs).
1062
+
1063
+ ## Getting Started
1064
+
1065
+ ### Next.js Installation
1066
+
1067
+ The fastest way to get started with Clerk is by following the [Next.js Quickstart](https://clerk.com/docs/quickstarts/nextjs?utm_source=github&utm_medium=clerk_nextjs).
1068
+
1069
+ You'll learn how to install `@clerk/nextjs`, set up your environment keys, add `<ClerkProvider>` to your application, use the Clerk middleware, and use Clerk's prebuilt components.
1070
+
1071
+ ### JavaScript Installation
1072
+
1073
+ The fastest way to get started with Clerk is by following the [JavaScript Quickstart](https://clerk.com/docs/quickstarts/javascript?utm_source=github&utm_medium=clerk_js).
1074
+
1075
+ You'll learn how to add the ClerkJS SDK to your application (either through `<script>` tag or NPM module) and use Clerk's prebuilt components.
1076
+
1077
+ ## Community
1078
+
1079
+ - Join our official community [Discord server](https://clerk.com/discord)
1080
+
1081
+ ## Advanced Middleware Configuration
1082
+
1083
+ ```typescript
1084
+ export default clerkMiddleware(async (auth, req) => {
1085
+ if (isProtectedRoute(req)) {
1086
+ await auth.protect();
1087
+ }
1088
+
1089
+ if (isAdminRoute(req)) {
1090
+ await auth.protect({ role: 'org:admin' });
1091
+ }
1092
+
1093
+ if (isCSPRoute(req)) {
1094
+ req.headers.set('Content-Security-Policy', csp.replace(/\n/g, ''));
1095
+ }
1096
+ });
1097
+ ```
1098
+
1099
+ ```typescript
1100
+ export const config = {
1101
+ matcher: [
1102
+ '/((?!.*\\..*|_next).*)', // Don't run middleware on static files
1103
+ '/', // Run middleware on index page
1104
+ '/(api|trpc)(.*)',
1105
+ ], // Run middleware on API routes
1106
+ };
1107
+ ```
1108
+
1109
+ ## Example Components
1110
+
1111
+ ```typescript
1112
+ function GreetingWithHook() {
1113
+ // Use the useUser hook to get the Clerk.user object
1114
+ // This hook causes a re-render on user changes
1115
+ const { isLoaded, isSignedIn, user } = useUser();
1116
+
1117
+ if (!isLoaded || !isSignedIn) {
1118
+ // You can handle the loading or signed state separately
1119
+ return null;
1120
+ }
1121
+
1122
+ return <div>Hello, {user.firstName}!</div>;
1123
+ }
1124
+ ```
1125
+
1126
+ ## Authentication Protection Details
1127
+
1128
+ `auth` includes a single property, the `protect()` method, which you can use in two ways:
1129
+ - to check if a user is authenticated (signed in)
1130
+ - to check if a user is authorized (has the correct roles or permissions) to access something, such as a component or a route handler
1131
+
1132
+ The following table describes how auth.protect() behaves based on user authentication or authorization status:
1133
+
1134
+ | Authenticated | Authorized | `auth.protect()` will |
1135
+ | - | - | - |
1136
+ | Yes | Yes | Return the [`Auth`](https://clerk.com/docs/references/backend/types/auth-object) object. |
1137
+ | Yes | No | Return a `404` error. |
1138
+ | No | No | Redirect the user to the sign-in page*. |
1139
+
1140
+ > [!IMPORTANT]
1141
+ > *For non-document requests, such as API requests, `auth.protect()` returns a `404` error to users who aren't authenticated.
1142
+
1143
+ `auth.protect()` can be used to check if a user is authenticated or authorized to access certain parts of your application or even entire routes. See detailed examples in the [dedicated guide](https://clerk.com/docs/organizations/verify-user-permissions).
1144
+
1145
+ ## auth() Helper Details
1146
+
1147
+ The `auth()` helper returns the [`Auth`](https://clerk.com/docs/references/backend/types/auth-object) object of the currently active user, as well as the [`redirectToSignIn()`](https://clerk.com/docs/references/nextjs/auth#redirect-to-sign-in) method.
1148
+
1149
+ - Only available for App Router.
1150
+ - Only works on the server-side, such as in Server Components, Route Handlers, and Server Actions.
1151
+ - Requires [`clerkMiddleware()`](https://clerk.com/docs/references/nextjs/clerk-middleware) to be configured.
1152
+
1153
+ ## currentUser() Details
1154
+
1155
+ - calls `fetch()`, so it is automatically deduped per request.
1156
+ - uses the [`GET /v1/users/{user_id}`](https://clerk.com/docs/reference/backend-api/tag/Users#operation/GetUser) endpoint.
1157
+ - counts towards the [Backend API request rate limit](https://clerk.com/docs/backend-requests/resources/rate-limits).
1158
+
1159
+ **Example:**
1160
+ ```tsx
1161
+ // app/page.tsx
1162
+ import { currentUser } from '@clerk/nextjs/server'
1163
+
1164
+ export default async function Page() {
1165
+ const user = await currentUser()
1166
+
1167
+ if (!user) return <div>Not signed in</div>
1168
+
1169
+ return <div>Hello {user?.firstName}</div>
1170
+ }
1171
+ ```
1172
+
1173
+ ## Advanced SignIn Button Examples
1174
+
1175
+ ```tsx
1176
+ <SignInButton
1177
+ mode='modal'
1178
+ forceRedirectUrl='/protected'
1179
+ signUpForceRedirectUrl='/protected'
1180
+ >
1181
+ Sign in button (force)
1182
+ </SignInButton>
1183
+
1184
+ <SignInButton
1185
+ mode='modal'
1186
+ oauthFlow='popup'
1187
+ forceRedirectUrl='/protected'
1188
+ signUpForceRedirectUrl='/protected'
1189
+ >
1190
+ Sign in button (force, popup)
1191
+ </SignInButton>
1192
+ ```
1193
+
1194
+ ## Type Definitions
1195
+
1196
+ ```typescript
1197
+ import type { OrganizationResource } from './organization';
1198
+ import type { ClerkResource } from './resource';
1199
+ import type { PublicUserData } from './session';
1200
+ import type { OrganizationMembershipJSONSnapshot } from './snapshots';
1201
+ import type { Autocomplete } from './utils';
1202
+
1203
+ interface Base {
1204
+ permission: string;
1205
+ role: string;
1206
+ }
1207
+ ```
1208
+
1209
+ ## About Clerk
1210
+
1211
+ Clerk helps developers build user management. We provide streamlined user experiences for your users to sign up, sign in, and manage their profile.
1212
+
1213
+ This repository contains all the Clerk JavaScript SDKs under the `@clerk` namespace.
1214
+
1215
+ ## Documentation
1216
+
1217
+ Clerk's full documentation is available at [clerk.com/docs](https://clerk.com/docs?utm_source=github&utm_medium=clerk_js_repo_readme).
1218
+
1219
+ - **We recommend starting with the [quickstart guides](https://clerk.com/docs/quickstarts/overview?utm_source=github&utm_medium=clerk_js_repo_readme).** They'll help you quickly add Clerk to your application. If you're starting a new project and aren't sure what to pick, check out our most popular quickstart: [Next.js](https://clerk.com/docs/quickstarts/nextjs?utm_source=github&utm_medium=clerk_js_repo_readme).
1220
+