From ada4bd0444a117550c8467d9ec7ca52b28d43307 Mon Sep 17 00:00:00 2001 From: Lennart Date: Tue, 12 Dec 2023 10:11:37 +0100 Subject: [PATCH] fix(nextjs): Use dynamic imports in ClerkProvider (#2292) * fix(nextjs): Use dynamic imports for ClerkProvider * chore(repo): Add changeset * fix(nextjs): Try another dynamic import * fix(nextjs): Typo * fix(nextjs): Try reverting a change --- .changeset/selfish-books-matter.md | 36 +++++++++++++++++++ .../src/client-boundary/ClerkProvider.tsx | 21 ++++++++--- 2 files changed, 52 insertions(+), 5 deletions(-) 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 0000000000..752b7c6b4c --- /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 3624aefd6e..95189e9a9e 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 ; }