From ea57cfeccb803244ce404b64692077b0ba52ca16 Mon Sep 17 00:00:00 2001 From: LekoArts Date: Fri, 8 Dec 2023 11:55:09 +0100 Subject: [PATCH 1/5] fix(nextjs): Use dynamic imports for ClerkProvider --- .../src/client-boundary/ClerkProvider.tsx | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/nextjs/src/client-boundary/ClerkProvider.tsx b/packages/nextjs/src/client-boundary/ClerkProvider.tsx index 3624aefd6e1..e178a4af7c2 100644 --- a/packages/nextjs/src/client-boundary/ClerkProvider.tsx +++ b/packages/nextjs/src/client-boundary/ClerkProvider.tsx @@ -1,19 +1,30 @@ 'use client'; -import { useRouter } from 'next/compat/router'; import React from 'react'; -import { ClientClerkProvider } from '../app-router/client/ClerkProvider'; import { ClerkProvider as PageClerkProvider } from '../pages/ClerkProvider'; import { type NextClerkProviderProps } from '../types'; /** * This is a compatibility layer to support a single ClerkProvider component in both the app and pages routers. + * It also needs to support both Next.js before and after v13, hence the dynamic imports for certain modules. */ export function ClerkProvider(props: NextClerkProviderProps) { - const router = useRouter(); + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { useRouter } = require('next/compat/router'); + const router = useRouter(); - const Provider = router ? PageClerkProvider : ClientClerkProvider; + return router ? : ; + } catch (error) { + // Silently ignore the error + return ; + } +} + +function AppClerkProvider(props: NextClerkProviderProps) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { ClientClerkProvider } = require('../app-router/client/ClerkProvider'); - return ; + return ; } From ae42e7d47f4c9b7ca3d6d746b31315d39dd488d7 Mon Sep 17 00:00:00 2001 From: LekoArts Date: Fri, 8 Dec 2023 12:05:58 +0100 Subject: [PATCH 2/5] chore(repo): Add changeset --- .changeset/selfish-books-matter.md | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .changeset/selfish-books-matter.md diff --git a/.changeset/selfish-books-matter.md b/.changeset/selfish-books-matter.md new file mode 100644 index 00000000000..752b7c6b4cc --- /dev/null +++ b/.changeset/selfish-books-matter.md @@ -0,0 +1,36 @@ +--- +'@clerk/nextjs': patch +--- + +Use dynamic imports in `` which you import from `@clerk/nextjs`. + +Users on Next.js 12 and older can run into errors like these: + +```shell +error - ./node_modules/@clerk/nextjs/dist/esm/app-router/client/ClerkProvider.js:10:22 +Module not found: Can't resolve 'next/navigation' +``` + +The aforementioned `` component contains code for both Next.js 12 (+ older) and Next.js 13 (+ newer). On older versions it can't find the imports only available in newer versions. + +If you're seeing these errors, you have to do two things: + +1. Update `@clerk/nextjs` to this version +1. Update your `next.config.js` to ignore these imports: + + ```js + const webpack = require('webpack'); + + /** @type {import('next').NextConfig} */ + const nextConfig = { + reactStrictMode: true, + webpack(config) { + config.plugins.push(new webpack.IgnorePlugin({ resourceRegExp: /^next\/(navigation|headers|compat\/router)$/ })) + return config; + } + } + + module.exports = nextConfig + ``` + + It is safe to ignore these modules as your Next.js 12 app won't hit these code paths. From e9e079f6fecc39a9bb7348b9c0f4d87b4179209d Mon Sep 17 00:00:00 2001 From: LekoArts Date: Mon, 11 Dec 2023 08:19:44 +0100 Subject: [PATCH 3/5] fix(nextjs): Try another dynamic import --- packages/nextjs/src/pages/ClerkProvider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/nextjs/src/pages/ClerkProvider.tsx b/packages/nextjs/src/pages/ClerkProvider.tsx index 2aa571720c1..5afd5b21bd0 100644 --- a/packages/nextjs/src/pages/ClerkProvider.tsx +++ b/packages/nextjs/src/pages/ClerkProvider.tsx @@ -1,5 +1,4 @@ import { __internal__setErrorThrowerOptions, ClerkProvider as ReactClerkProvider } from '@clerk/clerk-react'; -import { useRouter } from 'next/router'; import React from 'react'; import { ClerkNextOptionsProvider } from '../client-boundary/NextOptionsContext'; @@ -12,6 +11,8 @@ __internal__setErrorThrowerOptions({ packageName: '@clerk/nextjs' }); export function ClerkProvider({ children, ...props }: NextClerkProviderProps): JSX.Element { const { __unstable_invokeMiddlewareOnAuthStateChange = true } = props; + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { useRouter } = require('next/router'); const { push } = useRouter(); ReactClerkProvider.displayName = 'ReactClerkProvider'; From 8a6f0424dc01fa6574443273da72c10fc1565dd5 Mon Sep 17 00:00:00 2001 From: LekoArts Date: Mon, 11 Dec 2023 08:28:53 +0100 Subject: [PATCH 4/5] fix(nextjs): Typo --- packages/nextjs/src/client-boundary/ClerkProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/src/client-boundary/ClerkProvider.tsx b/packages/nextjs/src/client-boundary/ClerkProvider.tsx index e178a4af7c2..95189e9a9eb 100644 --- a/packages/nextjs/src/client-boundary/ClerkProvider.tsx +++ b/packages/nextjs/src/client-boundary/ClerkProvider.tsx @@ -15,7 +15,7 @@ export function ClerkProvider(props: NextClerkProviderProps) { const { useRouter } = require('next/compat/router'); const router = useRouter(); - return router ? : ; + return router ? : ; } catch (error) { // Silently ignore the error return ; From d864e20447d1786cf940ce7ce8400350fb37d00f Mon Sep 17 00:00:00 2001 From: LekoArts Date: Mon, 11 Dec 2023 09:47:32 +0100 Subject: [PATCH 5/5] fix(nextjs): Try reverting a change --- packages/nextjs/src/pages/ClerkProvider.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/nextjs/src/pages/ClerkProvider.tsx b/packages/nextjs/src/pages/ClerkProvider.tsx index 5afd5b21bd0..2aa571720c1 100644 --- a/packages/nextjs/src/pages/ClerkProvider.tsx +++ b/packages/nextjs/src/pages/ClerkProvider.tsx @@ -1,4 +1,5 @@ import { __internal__setErrorThrowerOptions, ClerkProvider as ReactClerkProvider } from '@clerk/clerk-react'; +import { useRouter } from 'next/router'; import React from 'react'; import { ClerkNextOptionsProvider } from '../client-boundary/NextOptionsContext'; @@ -11,8 +12,6 @@ __internal__setErrorThrowerOptions({ packageName: '@clerk/nextjs' }); export function ClerkProvider({ children, ...props }: NextClerkProviderProps): JSX.Element { const { __unstable_invokeMiddlewareOnAuthStateChange = true } = props; - // eslint-disable-next-line @typescript-eslint/no-var-requires - const { useRouter } = require('next/router'); const { push } = useRouter(); ReactClerkProvider.displayName = 'ReactClerkProvider';