Docs/Tutorial
// tutorial
Creare una pagina privata
In ZeroToShip tutto quello che sta sotto /app/dashboard/ è già protetto. Non devi controllare l'auth in ogni pagina: lo fa il layout una volta sola.
1. Il layout protetto
Dentro app/dashboard/layout.tsx c'è un server component che chiama supabase.auth.getUser(). Se non c'è utente, redirect al login:
import { redirect } from "next/navigation";
import { createClient } from "@/libs/supabase/server";
import config from "@/config";
export default async function LayoutPrivate({ children }) {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) redirect(config.auth.loginUrl);
return <>{children}</>;
}config.auth.loginUrl è definito in config.ts (default: /signin).
2. Aggiungi una nuova pagina
Crea una cartella dentro /app/dashboard/. Il file page.tsx è già protetto: il layout gira prima della pagina.
export const dynamic = "force-dynamic";
export default async function Impostazioni() {
return (
<main className="p-8">
<h1>Impostazioni</h1>
<p>Solo utenti loggati vedono questa pagina.</p>
</main>
);
}dynamic = "force-dynamic" ci serve perché la pagina dipende dai cookie dell'utente e Next non deve provare a pre-renderizzarla staticamente.
3. Leggi i dati dell'utente
Dato che è server component, hai accesso diretto al client server di Supabase. Recuperi l'utente e — se vuoi — leggi il suo profilo dal database:
import { createClient } from "@/libs/supabase/server";
export default async function Impostazioni() {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
const { data: profile } = await supabase
.from("profiles")
.select("*")
.eq("id", user.id)
.single();
return (
<main className="p-8">
<h1>Ciao {user.email}</h1>
<p>Accesso: {profile?.has_access ? "attivo" : "non attivo"}</p>
</main>
);
}4. Sezione privata parallela
Se vuoi un'altra sezione protetta fuori da /dashboard (es. /admin), copia lo stesso pattern: crea app/admin/layout.tsx con il check getUser() + redirect() e ci sei. Vuoi anche un check di ruolo? Leggi profile.role dal DB nel layout e redirect se non è admin.