Tutorials > Protected API Calls
Go into the /app/api folder – any file named route.js is your API endpoint! ✨ For an extra dash of simplicity, reach for the /libs/api.ts helper (it's like an axios wizard with interceptors).
1. Auto error messaging for the general cases such as Please Login , Paid Plan Required to use this feature etc.
2. Redirect to login page upon error 401
3. Add /api as a base URL: converts /api/leads → /leads
🍪 Supabase has your back with authentication using cookies – it's automatic! 🚀 Just fire off a regular API call on the front-end, like a breeze:
1
2 "use client"
3
4 import { useState } from "react";
5 import apiClient from "@/libs/api";
6
7 const UserDetails = () => {
8 const [isLoading, setIsLoading] = useState(false);
9 const supabase = createServerComponentClient({ cookies });
10
11 const {
12 data: { session },
13 } = await supabase.auth.getSession();
14
15 const saveUser = async () => {
16 setIsLoading(true);
17
18 try {
19 const { data } = await apiClient.post("/user", {
20 email: session.user.email,
21 });
22
23 console.log(data);
24 } catch (e) {
25 console.error(e?.message);
26 } finally {
27 setIsLoading(false);
28 }
29 };
30
31 return (
32 <button className="btn btn-primary" onClick={() => saveUser()}>
33 {isLoading && (
34 <span className="loading loading-spinner loading-sm"></span>
35 )}
36 Save User
37 </button>
38 );
39 };
40
41 export default UserProfile;
42
🔙 On the backend, we grab the session magic and use it to fetch the user from the database. But first things first – configure that database! 🛠️ Your API file is the secret sauce and should have a vibe like this:
1
2 import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
3 import { NextResponse } from "next/server";
4 import { cookies } from "next/headers";
5
6 export const dynamic = "force-dynamic";
7
8 export async function POST(req) {
9 const supabase = createRouteHandlerClient({ cookies });
10 const { data } = await supabase.auth.getSession();
11 const { session } = data;
12
13 // Check authentication by the object returned by Supabase
14 if (session) {
15 const body = await req.json();
16
17 if (!body.email) {
18 return NextResponse.json({ error: "Email is required" }, { status: 400 });
19 }
20
21 try {
22 // For this call, you need to create a table named "users" in your database
23 const { data } = await supabase
24 .from("users")
25 .insert({ email: body.email })
26 .select();
27
28 return NextResponse.json({ data }, { status: 200 });
29 } catch (e) {
30 console.error(e);
31 return NextResponse.json(
32 { error: "Something went wrong" },
33 { status: 500 }
34 );
35 }
36 } else {
37 // Unauthenticated
38 NextResponse.json({ error: "Not signed in" }, { status: 401 });
39 }
40 }
41