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. diff --git a/packages/nextjs/src/client-boundary/ClerkProvider.tsx b/packages/nextjs/src/client-boundary/ClerkProvider.tsx index 3624aefd6e1..95189e9a9eb 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 ; }