A secure, multi-user bookmark manager with real-time synchronization, built with Next.js App Router and Supabase.
- Authentication: Google OAuth login (Supabase Auth).
- Security: Row Level Security (RLS) ensures users only see their own data.
- Real-time: Instant updates across tabs using Supabase Realtime.
- Performance: Server Actions and Optimistic updates (via
router.refresh).
Update .env with your Supabase credentials:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key- Create a new Supabase project.
- Go to the SQL Editor in your Supabase dashboard.
- Copy and paste the contents of
supabase_schema.sqland run it. - Go to Authentication -> Providers and enable Google.
- (Optional for local dev) Add
http://localhost:3000to your Redirect URLs in Supabase Authentication settings.
npm install
npm run devOpen http://localhost:3000.
If you encounter a 400 (Bad Request) error during login, it typically means Supabase rejected the authentication request.
Potential Causes:
- Redirect URL not allowed: The URL
http://localhost:3000/auth/callbackis not in your Supabase "Redirect URLs" allowlist. - Google Provider not enabled/configured: The Google login provider isn't fully set up in Supabase.
- Google Cloud Misconfiguration: The Authorized Redirect URI in Google Cloud Console is incorrect.
How to Fix:
- Supabase - Redirect URLs:
- Go to Authentication -> URL Configuration.
- Add
http://localhost:3000/auth/callbackto Redirect URLs.
- Supabase - Google Provider:
- Go to Authentication -> Providers -> Google.
- Ensure it is Enabled.
- Verify Client ID and Client Secret match your Google Cloud credentials.
- Google Cloud Console:
- Ensure your Authorized redirect URI is set to
https://<your-project-ref>.supabase.co/auth/v1/callback(your Supabase Callback URL, NOT localhost).
- Ensure your Authorized redirect URI is set to
If you don't see bookmarks appearing instantly in other tabs:
- Enable Realtime: Realtime is disabled by default for new tables.
- Go to Supabase Dashboard -> Database -> Publications.
- Ensure
supabase_realtimeincludes thebookmarkstable. - Or via SQL:
alter publication supabase_realtime add table bookmarks;
- Check RLS: Ensure your Row Level Security policies allow
SELECTfor your user.
- Push to GitHub.
- Import project into Vercel.
- Add the
NEXT_PUBLIC_SUPABASE_URLandNEXT_PUBLIC_SUPABASE_ANON_KEYenvironment variables in Vercel. - Update your Supabase Authentication Redirect URLs to include your Vercel deployment URL (e.g.,
https://your-app.vercel.app/auth/callback). - Update Google Cloud Console Authorized Redirect URIs with the production URL.
Challenge: Next.js App Router uses Server Components by default, which don't automatically re-render when data changes in the database.
Solution: We used a client-side component (RealtimeBookmarks) to subscribe to Supabase Postgres Changes. When a change is detected (INSERT/DELETE), it calls router.refresh(). This triggers a soft refresh of the current route, causing Server Components to re-fetch data without losing client-side state (like scroll position).
Challenge: Protecting routes and managing sessions securely.
Solution: specific Supabase middleware manages the session refresh and protects routes by checking for an active user session, redirecting unauthenticated users to /login.