Skip to content

Commit

Permalink
Merge pull request #276 from ixartz/clerk-v5
Browse files Browse the repository at this point in the history
feat: upgrade to Clerk v5 and use Clerk's Core 2
  • Loading branch information
ixartz committed May 7, 2024
2 parents b99cf52 + 566b4c0 commit ef59975
Show file tree
Hide file tree
Showing 12 changed files with 634 additions and 608 deletions.
8 changes: 0 additions & 8 deletions README.md
Expand Up @@ -399,14 +399,6 @@ npm run db:studio

Then, you can open https://local.drizzle.studio with your favorite browser to explore your database.

### Known warnings

#### webpack.cache.PackFileCacheStrategy

Warning: webpack.cache.PackFileCacheStrategy Serializing big strings (104kiB) impacts deserialization performance (consider using Buffer instead and decode when needed)

This warning is caused by using `Clerk` and `next-intl` middlewares. It only happens when both middlewares are used together.

### VSCode information (optional)

If you are VSCode users, you can have a better integration with VSCode by installing the suggested extension in `.vscode/extension.json`. The starter code comes up with Settings for a seamless integration with VSCode. The Debug configuration is also provided for frontend and backend debugging experience.
Expand Down
1,132 changes: 559 additions & 573 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
40 changes: 23 additions & 17 deletions src/middleware.ts
@@ -1,5 +1,5 @@
import { authMiddleware, redirectToSignIn } from '@clerk/nextjs';
import type { NextRequest } from 'next/server';
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server';
import type { NextFetchEvent, NextRequest } from 'next/server';
import createMiddleware from 'next-intl/middleware';

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

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

beforeAuth: (req) => {
// Execute next-intl middleware before Clerk's auth middleware
return intlMiddleware(req);
},
export default function middleware(
request: NextRequest,
event: NextFetchEvent,
) {
if (
request.nextUrl.pathname.includes('/sign-in') ||
request.nextUrl.pathname.includes('/sign-up') ||
isProtectedRoute(request)
) {
return 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);
})(request, event);
}

return intlMiddleware(request);
}

export const config = {
matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'],
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 ef59975

Please sign in to comment.