Skip to content

Commit

Permalink
feat: upgrade to Clerk v5 and use Clerk's Core 2
Browse files Browse the repository at this point in the history
  • Loading branch information
ixartz committed May 7, 2024
1 parent b99cf52 commit c1978f1
Show file tree
Hide file tree
Showing 13 changed files with 547 additions and 495 deletions.
2 changes: 0 additions & 2 deletions .env
Expand Up @@ -15,8 +15,6 @@ DATABASE_URL=file:next-js-boilerplate.db
# Clerk authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_b3Blbi1zdGlua2J1Zy04LmNsZXJrLmFjY291bnRzLmRldiQ

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in

######## [BEGIN] SENSITIVE DATA ######## For security reason, don't update the following variables (secret key) directly in this file.
######## Please create a new file named `.env.local`, all environment files ending with `.local` won't be tracked by Git.
######## After creating the file, you can add the following variables.
Expand Down
955 changes: 490 additions & 465 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -26,8 +26,8 @@
"prepare": "husky"
},
"dependencies": {
"@clerk/localizations": "^1.28.4",
"@clerk/nextjs": "^4.30.1",
"@clerk/localizations": "^2.3.0",
"@clerk/nextjs": "^5.0.6",
"@hookform/resolvers": "^3.3.4",
"@libsql/client": "^0.6.0",
"@logtail/pino": "^0.4.21",
Expand Down
2 changes: 1 addition & 1 deletion src/app/[locale]/(auth)/(center)/layout.tsx
@@ -1,4 +1,4 @@
import { auth } from '@clerk/nextjs';
import { auth } from '@clerk/nextjs/server';
import { redirect } from 'next/navigation';

export default function CenteredLayout(props: { children: React.ReactNode }) {
Expand Down
@@ -1,6 +1,8 @@
import { SignIn } from '@clerk/nextjs';
import { getTranslations } from 'next-intl/server';

import { getI18nPath } from '@/utils/Helpers';

export async function generateMetadata(props: { params: { locale: string } }) {
const t = await getTranslations({
locale: props.params.locale,
Expand All @@ -13,6 +15,8 @@ export async function generateMetadata(props: { params: { locale: string } }) {
};
}

const SignInPage = () => <SignIn />;
const SignInPage = (props: { params: { locale: string } }) => (
<SignIn path={getI18nPath('/sign-in', props.params.locale)} />
);

export default SignInPage;
@@ -1,6 +1,8 @@
import { SignUp } from '@clerk/nextjs';
import { getTranslations } from 'next-intl/server';

import { getI18nPath } from '@/utils/Helpers';

export async function generateMetadata(props: { params: { locale: string } }) {
const t = await getTranslations({
locale: props.params.locale,
Expand All @@ -13,6 +15,8 @@ export async function generateMetadata(props: { params: { locale: string } }) {
};
}

const SignUpPage = () => <SignUp />;
const SignUpPage = (props: { params: { locale: string } }) => (
<SignUp path={getI18nPath('/sign-up', props.params.locale)} />
);

export default SignUpPage;
@@ -1,6 +1,8 @@
import { UserProfile } from '@clerk/nextjs';
import { getTranslations } from 'next-intl/server';

import { getI18nPath } from '@/utils/Helpers';

export async function generateMetadata(props: { params: { locale: string } }) {
const t = await getTranslations({
locale: props.params.locale,
Expand All @@ -12,9 +14,11 @@ export async function generateMetadata(props: { params: { locale: string } }) {
};
}

const UserProfilePage = () => (
const UserProfilePage = (props: { params: { locale: string } }) => (
<div className="my-6 -ml-16">
<UserProfile />
<UserProfile
path={getI18nPath('/dashboard/user-profile', props.params.locale)}
/>
</div>
);

Expand Down
4 changes: 2 additions & 2 deletions src/app/[locale]/(auth)/layout.tsx
Expand Up @@ -25,8 +25,8 @@ export default function AuthLayout(props: {
localization={clerkLocale}
signInUrl={signInUrl}
signUpUrl={signUpUrl}
afterSignInUrl={dashboardUrl}
afterSignUpUrl={dashboardUrl}
signInFallbackRedirectUrl={dashboardUrl}
signUpFallbackRedirectUrl={dashboardUrl}
>
{props.children}
</ClerkProvider>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Hello.tsx
@@ -1,4 +1,4 @@
import { currentUser } from '@clerk/nextjs';
import { currentUser } from '@clerk/nextjs/server';
import { getTranslations } from 'next-intl/server';

const Hello = async () => {
Expand Down
2 changes: 0 additions & 2 deletions src/libs/Env.ts
Expand Up @@ -12,7 +12,6 @@ export const Env = createEnv({
client: {
NEXT_PUBLIC_APP_URL: z.string().optional(),
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1),
NEXT_PUBLIC_CLERK_SIGN_IN_URL: z.string().min(1),
},
// You need to destructure all the keys manually
runtimeEnv: {
Expand All @@ -23,6 +22,5 @@ export const Env = createEnv({
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:
process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
NEXT_PUBLIC_CLERK_SIGN_IN_URL: process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL,
},
});
21 changes: 5 additions & 16 deletions src/middleware.ts
@@ -1,5 +1,4 @@
import { authMiddleware, redirectToSignIn } from '@clerk/nextjs';
import type { NextRequest } from 'next/server';
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
import createMiddleware from 'next-intl/middleware';

import { AppConfig } from './utils/AppConfig';
Expand All @@ -10,22 +9,12 @@ const intlMiddleware = createMiddleware({
defaultLocale: AppConfig.defaultLocale,
});

export default authMiddleware({
publicRoutes: (req: NextRequest) =>
!req.nextUrl.pathname.includes('/dashboard'),
const isProtectedRoute = createRouteMatcher(['/:locale/dashboard(.*)']);

beforeAuth: (req) => {
// Execute next-intl middleware before Clerk's auth middleware
return intlMiddleware(req);
},
export default clerkMiddleware((auth, req) => {
if (isProtectedRoute(req)) auth().protect();

// eslint-disable-next-line consistent-return
afterAuth(auth, req) {
// Handle users who aren't authenticated
if (!auth.userId && !auth.isPublicRoute) {
return redirectToSignIn({ returnBackUrl: req.url });
}
},
return intlMiddleware(req);
});

export const config = {
Expand Down
20 changes: 20 additions & 0 deletions src/utils/Helpers.test.ts
@@ -0,0 +1,20 @@
import { AppConfig } from './AppConfig';
import { getI18nPath } from './Helpers';

describe('Helpers', () => {
describe('getI18nPath function', () => {
it('should not change the path for default language', () => {
const url = '/random-url';
const locale = AppConfig.defaultLocale;

expect(getI18nPath(url, locale)).toBe(url);
});

it('should prepend the locale to the path for non-default language', () => {
const url = '/random-url';
const locale = 'fr';

expect(getI18nPath(url, locale)).toMatch(/^\/fr/);
});
});
});
10 changes: 10 additions & 0 deletions src/utils/Helpers.ts
@@ -1,3 +1,5 @@
import { AppConfig } from './AppConfig';

export const getBaseUrl = () => {
if (process.env.NEXT_PUBLIC_APP_URL) {
return process.env.NEXT_PUBLIC_APP_URL;
Expand All @@ -9,3 +11,11 @@ export const getBaseUrl = () => {

return 'http://localhost:3000';
};

export const getI18nPath = (url: string, locale: string) => {
if (locale === AppConfig.defaultLocale) {
return url;
}

return `/${locale}${url}`;
};

0 comments on commit c1978f1

Please sign in to comment.