Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .changeset/selfish-books-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
'@clerk/nextjs': patch
---

Use dynamic imports in `<ClerkProvider />` 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 `<ClerkProvider />` 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.
21 changes: 16 additions & 5 deletions packages/nextjs/src/client-boundary/ClerkProvider.tsx
Original file line number Diff line number Diff line change
@@ -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 ? <PageClerkProvider {...props} /> : <AppClerkProvider {...props} />;
} catch (error) {
// Silently ignore the error
return <PageClerkProvider {...props} />;
}
}

function AppClerkProvider(props: NextClerkProviderProps) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { ClientClerkProvider } = require('../app-router/client/ClerkProvider');

return <Provider {...props} />;
return <ClientClerkProvider {...props} />;
}