Skip to content

Commit

Permalink
feat: next@15 compatibility (#1641)
Browse files Browse the repository at this point in the history
Co-authored-by: Bryce Kalow <[email protected]>
Co-authored-by: Dylan Staley <[email protected]>
  • Loading branch information
3 people authored Oct 23, 2024
1 parent 978a005 commit f826791
Show file tree
Hide file tree
Showing 26 changed files with 326 additions and 138 deletions.
4 changes: 2 additions & 2 deletions docs/advanced-usage/satellite-domains.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,9 @@ To access authentication state from a satellite domain, users will be transparen
// domain: 'http://localhost:3001',
}

export default clerkMiddleware((auth, req) => {
export default clerkMiddleware(async (auth, req) => {
if (isPublicRoute(req)) return // if it's a public route, do nothing
auth().protect() // for any other route, require auth
await auth.protect() // for any other route, require auth
}, options)

export const config = {
Expand Down
2 changes: 1 addition & 1 deletion docs/authentication/social-connections/oauth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ import { auth, clerkClient } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'

export async function GET() {
const { userId } = auth()
const { userId } = await auth()

if (!userId) {
return NextResponse.json({ message: 'User not found' })
Expand Down
4 changes: 2 additions & 2 deletions docs/backend-requests/making/custom-session-token.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ This guide will show you how to customize a session token to include additional
import { auth } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'

export default function Page() {
const { sessionClaims } = auth()
export default async function Page() {
const { sessionClaims } = await auth()

const firstName = sessionClaims?.fullName

Expand Down
13 changes: 7 additions & 6 deletions docs/components/clerk-provider.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ The `<ClerkProvider>` component must be added to your React entrypoint.

<Tabs type="framework" items={["Next.js", "React"]}>
<Tab>
By default, the `<ClerkProvider>` component has a server component wrapper in order to access header information. This means anything wrapped by the provider will be opted into dynamic rendering at request time.

If you would prefer not to be opted into dynamic rendering, such as for static-optimized or ISR pages, you can either use `<ClerkProvider>` in a client component, or ensure the content is not wrapped by `<ClerkProvider>`. Instead of wrapping your application root with the provider, you can place it further down the tree to wrap route groups that require authentication.

For example, if your project includes a set of landing/marketing pages and a dashboard that requires sign-in, you can create separate route groups for marketing and dashboard pages. By adding `<ClerkProvider>` to the `(dashboard)/layout.jsx` file, only the dashboard routes will opt into dynamic rendering, while the marketing routes remain statically optimized.

<CodeBlockTabs type="router" options={["App Router", "Pages Router"]}>
```tsx {{ filename: 'app/layout.tsx' }}
import React from 'react'
Expand Down Expand Up @@ -268,6 +262,13 @@ The `<ClerkProvider>` component must be added to your React entrypoint.
- `InitialState`

Provide an initial state of the Clerk client during server-side rendering. You don't need to set this value yourself unless you're [developing an SDK](/docs/references/sdk/overview).

---

- `dynamic?`
- `boolean`

(For Next.js only) Indicates whether or not Clerk should make dynamic auth data available based on the current request. Defaults to `false`. Opts the application into dynamic rendering when `true`. For more information, see [Next.js rendering modes and Clerk](/docs/references/nextjs/rendering-modes).
</Properties>

[components-ref]: /docs/components/overview
Expand Down
2 changes: 1 addition & 1 deletion docs/custom-flows/user-impersonation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This guide will walk you through how to build a custom flow that handles user im
import ImpersonateUsers from './_components'

export default async function AccountPage() {
const { has } = auth()
const { has } = await auth()

// Protect the page
if (!has({ permission: 'org:admin:impersonate' })) {
Expand Down
10 changes: 5 additions & 5 deletions docs/guides/add-onboarding-flow.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ import { NextRequest, NextResponse } from 'next/server'
const isOnboardingRoute = createRouteMatcher(['/onboarding'])
const isPublicRoute = createRouteMatcher(['/public-route-example'])

export default clerkMiddleware((auth, req: NextRequest) => {
const { userId, sessionClaims, redirectToSignIn } = auth()
export default clerkMiddleware(async (auth, req: NextRequest) => {
const { userId, sessionClaims, redirectToSignIn } = await auth()

// For users visiting /onboarding, don't try to redirect
if (userId && isOnboardingRoute(req)) {
Expand Down Expand Up @@ -117,8 +117,8 @@ You will need a layout for the `/onboarding` route that will redirect users to t
import { auth } from '@clerk/nextjs/server'
import { redirect } from 'next/navigation'

export default function RootLayout({ children }: { children: React.ReactNode }) {
if (auth().sessionClaims?.metadata.onboardingComplete === true) {
export default async function RootLayout({ children }: { children: React.ReactNode }) {
if ((await auth()).sessionClaims?.metadata.onboardingComplete === true) {
redirect('/')
}

Expand Down Expand Up @@ -211,7 +211,7 @@ Now that there is a form to collect the user's onboarding information, you need
import { auth, clerkClient } from '@clerk/nextjs/server'

export const completeOnboarding = async (formData: FormData) => {
const { userId } = auth()
const { userId } = await auth()

if (!userId) {
return { message: 'No Logged In User' }
Expand Down
4 changes: 2 additions & 2 deletions docs/guides/authjs-migration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ This guide shows how to migrate an application using Auth.js (formerly NextAuth.
import { auth, currentUser } from '@clerk/nextjs/server'

export default async function Page() {
const { userId } = auth()
const { userId } = await auth()
console.log(userId)

return <p>Home Page</p>
Expand Down Expand Up @@ -249,7 +249,7 @@ This guide shows how to migrate an application using Auth.js (formerly NextAuth.
export default async function Page() {
const {
sessionClaims: { userId },
} = auth()
} = await auth()
console.log(userId)

return <p>Home Page</p>
Expand Down
8 changes: 4 additions & 4 deletions docs/guides/basic-rbac.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ This guide assumes that you're using Next.js App Router, but the concepts can be
import { Roles } from '@/types/global'
import { auth } from '@clerk/nextjs/server'

export const checkRole = (role: Roles) => {
const { sessionClaims } = auth()
export const checkRole = async (role: Roles) => {
const { sessionClaims } = await auth()
return sessionClaims?.metadata.role === role
}
```
Expand Down Expand Up @@ -124,9 +124,9 @@ This guide assumes that you're using Next.js App Router, but the concepts can be

const isAdminRoute = createRouteMatcher(['/admin(.*)'])

export default clerkMiddleware((auth, req) => {
export default clerkMiddleware(async (auth, req) => {
// Protect all routes starting with `/admin`
if (isAdminRoute(req) && auth().sessionClaims?.metadata?.role !== 'admin') {
if (isAdminRoute(req) && (await auth()).sessionClaims?.metadata?.role !== 'admin') {
const url = new URL('/', req.url)
return NextResponse.redirect(url)
}
Expand Down
6 changes: 3 additions & 3 deletions docs/guides/custom-redirects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ If you would like to override the `redirect_url` value and supply a custom redir

## Middleware

If you are using Next.js and want a more programmatically generated redirect option, you can use the [`auth().protect()`](/docs/references/nextjs/auth#protect) method in your [Clerk middleware](/docs/references/nextjs/clerk-middleware).
If you are using Next.js and want a more programmatically generated redirect option, you can use the [`auth.protect()`](/docs/references/nextjs/auth#protect) method in your [Clerk middleware](/docs/references/nextjs/clerk-middleware).

```tsx {{ filename: 'middleware.ts' }}
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'

const isProtectedRoute = createRouteMatcher(['/dashboard(.*)'])

export default clerkMiddleware((auth, req) => {
if (isProtectedRoute(req)) auth().protect()
export default clerkMiddleware(async (auth, req) => {
if (isProtectedRoute(req)) await auth.protect()
})

export const config = {
Expand Down
16 changes: 8 additions & 8 deletions docs/guides/force-organizations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ This guide will be written for Next.js applications using App Router, but the sa
```tsx
import { auth } from '@clerk/nextjs/server'

export default function Layout() {
const { orgId } = auth()
export default async function Layout() {
const { orgId } = await auth()

const hasActiveOrg = !!orgId
// ...
Expand Down Expand Up @@ -238,8 +238,8 @@ This guide will be written for Next.js applications using App Router, but the sa
```tsx {{ filename: 'middleware.ts' }}
import { clerkMiddleware } from '@clerk/nextjs/server'

export default clerkMiddleware((auth, req) => {
const { userId, orgId } = auth()
export default clerkMiddleware(async (auth, req) => {
const { userId, orgId } = await auth()

// Redirect signed in users to organization selection page if they are not active in an organization
if (userId && !orgId && req.nextUrl.pathname !== '/org-selection') {
Expand All @@ -266,8 +266,8 @@ This guide will be written for Next.js applications using App Router, but the sa
```tsx {{ filename: 'middleware.ts' }}
import { clerkMiddleware } from '@clerk/nextjs/server'

export default clerkMiddleware((auth, req) => {
const { userId, orgId } = auth()
export default clerkMiddleware(async (auth, req) => {
const { userId, orgId } = await auth()

// Redirect signed in users to organization selection page if they are not active in an organization
if (
Expand Down Expand Up @@ -367,9 +367,9 @@ This guide will be written for Next.js applications using App Router, but the sa
import { auth } from '@clerk/nextjs/server'
import { PropsWithChildren } from 'react'

export default function RequiredActiveOrgLayout(props: PropsWithChildren) {
export default async function RequiredActiveOrgLayout(props: PropsWithChildren) {
// Get the organization ID from the session
const { orgId } = auth()
const { orgId } = await auth()

// If the user has an active organization, render the children
if (orgId) {
Expand Down
10 changes: 5 additions & 5 deletions docs/integrations/databases/neon.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ This tutorial demonstrates how to integrate Neon Postgres with Clerk in a Next.j
```typescript {{ filename: 'middleware.ts', mark: [[3, 5]] }}
import { clerkMiddleware } from '@clerk/nextjs/server'

export default clerkMiddleware((auth) => {
auth().protect()
export default clerkMiddleware(async (auth) => {
await auth.protect()
})

export const config = {
Expand Down Expand Up @@ -152,7 +152,7 @@ This tutorial demonstrates how to integrate Neon Postgres with Clerk in a Next.j
import { eq } from 'drizzle-orm'

export async function createUserMessage(formData: FormData) {
const { userId } = auth()
const { userId } = await auth()
if (!userId) throw new Error('User not found')

const message = formData.get('message') as string
Expand All @@ -163,7 +163,7 @@ This tutorial demonstrates how to integrate Neon Postgres with Clerk in a Next.j
}

export async function deleteUserMessage() {
const { userId } = auth()
const { userId } = await auth()
if (!userId) throw new Error('User not found')

await db.delete(UserMessages).where(eq(UserMessages.user_id, userId))
Expand All @@ -184,7 +184,7 @@ This tutorial demonstrates how to integrate Neon Postgres with Clerk in a Next.j
import { auth } from '@clerk/nextjs/server'

export default async function Home() {
const { userId } = auth()
const { userId } = await auth()
if (!userId) throw new Error('User not found')
const existingMessage = await db.query.UserMessages.findFirst({
where: (messages, { eq }) => eq(messages.user_id, userId),
Expand Down
4 changes: 2 additions & 2 deletions docs/integrations/databases/supabase.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,9 @@ For interacting with the Supabase dashboard, you can either use the **Supabase i
import { auth } from '@clerk/nextjs/server'
import { createClient } from '@supabase/supabase-js'

export function createClerkSupabaseClientSsr() {
export async function createClerkSupabaseClientSsr() {
// The `useAuth()` hook is used to access the `getToken()` method
const { getToken } = auth()
const { getToken } = await auth()

return createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
Expand Down
8 changes: 8 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,10 @@
"title": "Clerk SDK versioning",
"href": "/docs/upgrade-guides/sdk-versioning"
},
{
"title": "Upgrading to @clerk/nextjs v6",
"href": "/docs/upgrade-guides/nextjs/v6"
},
{
"title": "Upgrading to Core 2",
"items": [
Expand Down Expand Up @@ -1659,6 +1663,10 @@
{
"title": "Integrate Clerk into your app with tRPC",
"href": "/docs/references/nextjs/trpc"
},
{
"title": "Next.js rendering modes and Clerk",
"href": "/docs/references/nextjs/rendering-modes"
}
]
]
Expand Down
Loading

0 comments on commit f826791

Please sign in to comment.