2024-09-09 web, development, javascript
Next.js 14 App with Clerk and Supabase
By O. Wolfson
This ariticle describes the process of building a Next.js 14 application with Clerk and Supabase. This app handles user authentication with Clerk and manages data with Supabase.
Demo:
My Example app, Depoloyed at Vercel.
Official Documentation:
Clerk and Next.js Quickstart. Clerk Docs
Clerk and Supabase. Supabase Docs
Deploy to production. Clerk Docs
Step 1: Initializing the Project
- Create Next.js 14 App:
- Install Dependencies:
Step 2: Environment Setup
Set up the environment for your Next.js project by integrating Clerk and Supabase. This involves obtaining the necessary API keys from both Clerk and Supabase and configuring them in your project.
-
Obtaining Clerk API Keys:
- Go to the Clerk Dashboard.
- Sign up or log in to your Clerk account.
- Create a new Application or select an existing one.
- Navigate to the 'API Keys' section in your Clerk dashboard.
-
Obtaining Supabase API Keys:
-
Visit the Supabase Dashboard.
-
Sign in or create a new Supabase account.
-
Create a new project or select an existing one.
-
Once your project dashboard is open, go to the 'Settings' > 'API' section.
-
You will find two keys here: the
anon
public key and theservice_role
secret key. For most client-side operations, theanon
key is what you'll use. -
You will also need Supabase's jwt secret key. To obtain this key, go to the 'Settings' > 'API'. You will find the jwt secret key here under the Config section.
In your Clerk application, use the lefthand menu to navigate to the JWT Templates page. Click on the button to create a new template based on Supabase. Name your template (I've named mine supabase, as in the example shown here in Supabase's Clerk Integration Docs) and click on the Create Template button. Enter your Supabase jwt secret key in the Signing Key input and apply changes. Once you have done this, you should be able to generate a token for your Supabase client.
For more information check out the Supabase's Clerk Integration Docs.
-
-
.env.local
Configuration: After obtaining your API keys, the next step is to securely add them to your Next.js application using an environment file.- Create a file named
.env.local
in the root of your Next.js project (if it doesn't already exist).
- Create a file named
add api keys to .env.local as follows:
This environment setup ensures that your application can communicate securely with Clerk and Supabase services. Remember, these keys should be kept secure and not exposed in client-side code beyond what is necessary for the functionalities provided by Clerk and Supabase.
Step 3: Clerk Integration
Integrating Clerk into your Next.js application involves setting up the ClerkProvider
in your main layout, creating a navigation bar with authentication controls, and setting up dedicated pages for sign-in and sign-up. Here's how to go about it:
-
Clerk Setup in
layout.tsx
: TheClerkProvider
component is used to wrap your application's root layout. This ensures that Clerk's authentication functionalities are accessible throughout your app.-
Open or create a
layout.tsx
file in your project. -
Import
ClerkProvider
from@clerk/nextjs
. -
You'll also need to import the
useRouter
hook fromnext/router
. -
Wrap your layout component's content with
ClerkProvider
, passing in the Clerk Frontend API key from your environment variables. -
Example implementation:
-
-
NavBar Component:
The
NavBar
component serves as the main navigation header for your application, providing links and authentication controls available globally.-
I recommend using Clerk's
UserButton
component to handle authentication controls like sign-out and account management. Here I have added the UserButton to anAuthButton
component that also handles the case where the user is not authenticated and offers a link to the sign-in page. If the user is logged in the UserButton will be displayed.
-
-
Creating Authentication Pages:
Dedicated pages for sign-in and sign-up provide a focused area for users to manage their authentication state.
-
Create two new pages in your Next.js application, typically named
sign-in.tsx
andsign-up.tsx
. -
Use Clerk's provided components such as
SignIn
andSignUp
to render the respective authentication forms. -
Example for
sign-in.tsx
: -
Similarly, set up the
sign-up.tsx
page with theSignUp
component.
-
By following these steps, you'll have integrated Clerk into your Next.js application, providing a seamless authentication experience for your users. Remember to style and customize your NavBar
and authentication pages to match the look and feel of your application.
Step 4: Supabase Integration
Integrating Supabase into your Next.js application involves initializing the Supabase client and configuring row-level security to manage data access. Here’s a guide on how to set this up:
- Initializing Supabase Client: To interact with Supabase, you need to initialize the Supabase client. This is done by creating a standard client for general operations and a Clerk-authenticated client for operations that require user authentication.
Standard Supabase Client:
-
Create a file named
lib/supabase.ts
. -
Import the
createClient
method from@supabase/supabase-js
. -
Initialize the Supabase client using the Supabase URL and ANON key from your environment variables.
-
Example:
Clerk-Authenticated Supabase Client:
Server-Side Supabase Client Setup
Server-side setup is crucial for operations that should be securely executed on the server, like direct database manipulations.
-
Import Clerk's Server-Side Auth Module:
-
Retrieve the Authentication Token:
-
Create the Supabase Client:
-
Usage:
- Use
supabaseServerClient
for server-side database operations.
- Use
Client-Side Supabase Client Setup
The client-side setup is used for operations that require real-time user interaction, like form submissions.
-
Import Clerk's Client-Side Auth Hook:
-
Initialize the Supabase Client Inside a React Component:
-
Usage:
- Use
supabaseClient
within your React components for client-side interactions.
- Use
-
Row-Level Security in Supabase: Row-level security (RLS) is a feature that allows you to control access to rows in a database table based on user attributes or other access policies. This is crucial for protecting sensitive data and ensuring that users can only access data they are permitted to see.
-
Setting Up RLS:
- In your Supabase dashboard, go to the table you want to apply RLS to.
- Enable Row-Level Security for the table.
- Create policies that define the conditions under which rows in this table can be accessed, updated, or deleted. For example, you can create a policy that allows users to only read rows where the user ID column matches their own user ID.
- Test these policies thoroughly to ensure they work as expected and do not inadvertently expose sensitive data.
-
Integrating RLS with Clerk:
- When using Clerk for authentication, ensure that the user's unique ID from Clerk is stored in your Supabase tables where needed (e.g., as a column in each row).
- Your RLS policies can then reference this ID to control access based on the authenticated user's ID.
-
By following these steps, you will successfully integrate Supabase into your Next.js application, complete with a standard client for general database operations and a Clerk-authenticated client for user-specific data access. Additionally, setting up row-level security ensures that your application's data access is secure and compliant with your access policies.