I have set up a Next.js application with authentication handled by Clerk.dev and data storage managed by Supabase. I am also using Zustand for state management. However, I am encountering an error that says "No storage option exists to persist the session, which may result in unexpected behavior when using auth."
"@clerk/nextjs": "^4.16.4",
"next": "^12.0.9",
"react": "17.0.2",
"zustand": "^4.3.8"
Here is a simplified version of my code:
File: utils\supabase.ts
import { createClient, SupabaseClient } from '@supabase/supabase-js';
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_KEY;
export const supabase: SupabaseClient = createClient(supabaseUrl, supabaseKey);
File: store\useUserStore.ts
import { create } from 'zustand';
import { supabase } from '../utils/supabase';
type User = {
id: string;
email: string;
custom_api: string;
bot_type: string;
discord_id: string;
};
type UserStore = {
userData: User | null;
status: 'idle' | 'loading' | 'error';
error: string | null;
fetchUser: (userId: string) => Promise<void>;
createUser: (userId: string, user: Partial<User>) => Promise<void>;
updateUser: (userId: string, updates: Partial<User>) => Promise<void>;
deleteUser: (userId: string) => Promise<void>;
};
export const useUserStore = create<UserStore>((set) => ({
userData: null,
status: 'idle',
error: null,
fetchUser: async (userId) => {
try {
set({ status: 'loading' });
const { data, error } = await supabase
.from('users')
.select()
.eq('id', userId)
if (error) {
throw new Error('Error fetching user');
}
set({ userData: data![0] ?? null, status: 'idle', error: null });
} catch (error) {
set({ status: 'error', error: error.message });
}
},
createUser: async (userId, user) => {
// code here
},
updateUser: async (userId, updates) => {
// code here
},
deleteUser: async (userId) => {
// code here
},
}));
The error message states that no storage option exists to persist the session, which could lead to unexpected behavior when using authentication. I want to enable the persistSession option but I'm unsure how to proceed.
For additional context, I am using Clerk.dev for authentication, connecting it to Supabase using JWT. I have also set up a Row-Level Security (RLS) policy for the SELECT operation, targeting all (public) roles and using a WITH CHECK expression.
I would greatly appreciate any guidance or suggestions on how to resolve this error and properly configure the session storage to work seamlessly with Clerk.dev, Supabase, and Zustand. Thank you!
Back then, my code was structured like this:
import { createClient } from '@supabase/supabase-js'
import { useSession } from '@clerk/nextjs'
/// .....
const supabaseClient = async supabaseAccessToken => {
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_KEY,
{
global: { headers: { Authorization: `Bearer ${supabaseAccessToken}` } }
}
)
return supabase
}
/// .....
export default function Messages() {
//...
const { session } = useSession()
//...
const supabaseAccessToken = await session.getToken({
template: 'Supabase'
})
const supabase = await supabaseClient(supabaseAccessToken)
const { data } = await supabase
.from('user')
.insert(
{
id: session.user.id,
email: session.user?.primaryEmailAddress?.emailAddress,
}
)
.select()
setUserSettings(data[0])
//...
This code looks messy because I'm doing it directly in a .tsx file. I want to use state management (Zustand) to improve the code structure and adhere to good practices.