From 1cb548b2dc9ab77b3d41fbf7eab7fa7f03712756 Mon Sep 17 00:00:00 2001 From: Fatuma Abdullahi <67555014+FatumaA@users.noreply.github.com> Date: Thu, 16 Apr 2026 11:19:36 +0300 Subject: [PATCH] Docs: add astro guide auth quickstart (#44495) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Adds an Astro auth guide ## What is the current behavior? No such guide ## What is the new behavior? Adds the guide Screenshot 2026-04-02 at 18 30 07 ## Additional context N/A ## Summary by CodeRabbit * **Documentation** * Added an Astro authentication quickstart covering Supabase setup, SSR configuration, required env vars, server-side auth flows, email confirmation handling, and testing the dev flow; includes end-to-end examples for sign-up, sign-in, sign-out, protected pages, and a dashboard walkthrough * **Navigation** * Added Astro to the Auth "Getting Started" navigation section --------- Co-authored-by: Chris Chinchilla --- .../NavigationMenu.constants.ts | 4 + .../guides/auth/quickstarts/astrojs.mdx | 662 ++++++++++++++++++ 2 files changed, 666 insertions(+) create mode 100644 apps/docs/content/guides/auth/quickstarts/astrojs.mdx diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index dbebd1e9a0e..a36c3f912b1 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -697,6 +697,10 @@ export const auth: NavMenuConstant = { name: 'Next.js', url: '/guides/auth/quickstarts/nextjs' as `/${string}`, }, + { + name: 'Astro', + url: '/guides/auth/quickstarts/astrojs', + }, { name: 'React', url: '/guides/auth/quickstarts/react', items: [] }, { name: 'React Native', diff --git a/apps/docs/content/guides/auth/quickstarts/astrojs.mdx b/apps/docs/content/guides/auth/quickstarts/astrojs.mdx new file mode 100644 index 00000000000..e0de5fba90f --- /dev/null +++ b/apps/docs/content/guides/auth/quickstarts/astrojs.mdx @@ -0,0 +1,662 @@ +--- +title: 'Use Supabase Auth with Astro' +subtitle: 'Learn how to configure Supabase Auth for Astro with server-side rendering.' +breadcrumb: 'Auth Quickstarts' +hideToc: true +--- + + + + + + + Head over to [database.new](https://database.new) and create a new Supabase project. + + Your new database has a table for storing your users. You can see that this table is currently empty by running some SQL in the [SQL Editor](/dashboard/project/_/sql/new). + + + + + + ```sql name=SQL_EDITOR + select * from auth.users; + ``` + + + + + + + + + + Create a new Astro app using the `npm create` command. + + <$Partial path="uiLibCta.mdx" /> + + + + + + ```bash name=Terminal + npm create astro@latest my-app + cd my-app + ``` + + + + + + + + + Install the `@supabase/supabase-js` client library, `@supabase/ssr` for server-side auth, and the `@astrojs/node` adapter to enable server-side rendering. + + + + + + ```bash name=Terminal + npm install @supabase/supabase-js @supabase/ssr @astrojs/node + ``` + + + + + + + + + Update your `astro.config.mjs` to enable server-side rendering with the Node adapter. + + + + + + ```js name=astro.config.mjs + import { defineConfig } from "astro/config"; + import node from "@astrojs/node"; + + export default defineConfig({ + output: "server", + adapter: node({ + mode: "standalone", + }), + }); + ``` + + + + + + + + + Create a `.env.local` file and populate with your Supabase connection variables: + + + + + + + + + ```text name=.env.local + PUBLIC_SUPABASE_URL=your-project-url + PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_key + ``` + + <$Partial path="api_settings_steps.mdx" variables={{ "framework": "astro", "tab": "frameworks" }} /> + + + + + + + + + Create a utility file to initialize the Supabase client with SSR support: + + + + + + ```ts name=src/lib/supabase.ts + import { createServerClient, parseCookieHeader } from "@supabase/ssr"; + import type { AstroCookies } from "astro"; + + const supabaseUrl = import.meta.env.PUBLIC_SUPABASE_URL + const supabasePublishableKey = import.meta.env.PUBLIC_SUPABASE_PUBLISHABLE_KEY + + export function createClient({ + request, + cookies, + }: { + request: Request; + cookies: AstroCookies; + }) { + return createServerClient( + supabaseUrl, + supabasePublishableKey, + { + cookies: { + getAll() { + return parseCookieHeader( + request.headers.get("Cookie") ?? "" + ); + }, + setAll(cookiesToSet) { + cookiesToSet.forEach(({ name, value, options }) => + cookies.set(name, value, options) + ); + }, + }, + } + ); + } + ``` + + + + + + + + + Create a new file at `src/actions/index.ts` to define server-side authentication actions for signing up, signing in, and signing out: + + + + + + ```ts name=src/actions/index.ts + import { defineAction } from "astro:actions"; + import { z } from "astro/zod"; + import { createClient } from "../lib/supabase"; + + export const server = { + signUp: defineAction({ + accept: "form", + input: z.object({ + email: z.string().email(), + password: z.string().min(6), + }), + handler: async (input, context) => { + try { + const supabase = createClient({ + request: context.request, + cookies: context.cookies, + }); + + const { error } = await supabase.auth.signUp({ + email: input.email, + password: input.password, + options: { + emailRedirectTo: "http://localhost:4321/auth/callback", + }, + }); + + if (error) { + return { + success: false, + message: error.message, + }; + } + + return { + success: true, + message: "Check your email to confirm your account", + }; + } catch (err) { + return { + success: false, + message: "Unexpected error", + }; + } + }, + }), + signIn: defineAction({ + accept: "form", + input: z.object({ + email: z.string().email(), + password: z.string(), + }), + handler: async (input, context) => { + try { + const supabase = createClient({ + request: context.request, + cookies: context.cookies, + }); + + const { error } = await supabase.auth.signInWithPassword({ + email: input.email, + password: input.password, + }); + + if (error) { + return { + success: false, + message: error.message, + }; + } + + return { + success: true, + message: "Signed in successfully", + }; + } catch (err) { + return { + success: false, + message: "Unexpected error", + }; + } + }, + }), + signOut: defineAction({ + handler: async (_, context) => { + try { + const supabase = createClient({ + request: context.request, + cookies: context.cookies, + }); + + await supabase.auth.signOut(); + + return { + success: true, + }; + } catch (err) { + return { + success: false, + message: "Failed to sign out", + }; + } + }, + }), + }; + ``` + + + + + + + + + Before users can confirm their email, update the Supabase email template to send the token hash to your callback URL. + + In your [Supabase project dashboard](/dashboard/project/_/auth/templates): + - Go to **Auth** > **Email Templates** + - Select the **Confirm signup** template + - Change `{{ .ConfirmationURL }}` to `{{ .SiteURL }}/auth/callback?token_hash={{ .TokenHash }}&type=email`. + - Change your [Site URL](/dashboard/project/_/auth/url-configuration) to `http://localhost:4321` + + + + + + ```html name=Email\ Template + {{ .SiteURL }}/auth/callback?token_hash={{ .TokenHash }}&type=email + ``` + + + + + + + + + Create a new file at `src/pages/auth/callback.astro` to handle the email confirmation callback. Extract the token from the URL and verify it with Supabase: + + + + + + ```astro name=src/pages/auth/callback.astro + --- + import { createClient } from "../../lib/supabase"; + import type { EmailOtpType } from "@supabase/supabase-js"; + + const supabase = createClient({ + request: Astro.request, + cookies: Astro.cookies, + }); + + const requestUrl = new URL(Astro.request.url); + const token_hash = requestUrl.searchParams.get('token_hash'); + const type = requestUrl.searchParams.get('type') as EmailOtpType | null; + + if (token_hash && type) { + const { error } = await supabase.auth.verifyOtp({ + token_hash, + type, + }); + + if (!error) { + return Astro.redirect("/dashboard"); + } + } + + return Astro.redirect("/auth/signin"); + --- + + + + Email Confirmation + + +

Confirming your email...

+ + + ``` + +
+ +
+ + + + + Create a new file at `src/pages/auth/signup.astro` with a sign-up form. Use a client-side event listener to handle form submission: + + + + + + ```astro name=src/pages/auth/signup.astro + --- + import { createClient } from "../../lib/supabase"; + + const supabase = createClient({ + request: Astro.request, + cookies: Astro.cookies, + }); + + const { data } = await supabase.auth.getUser(); + + if (data?.user) { + return Astro.redirect("/dashboard"); + } + --- + + + + Sign Up + + +

Sign Up

+ +
+ +
+
+ + +
+
+ + +
+ +
+

+ Already have an account? Sign in +

+ + + + + ``` + +
+ +
+ + + + + Create a new file at `src/pages/auth/signin.astro` with a sign-in form. Use a client-side event listener to handle form submission: + + + + + + ```astro name=src/pages/auth/signin.astro + --- + import { createClient } from "../../lib/supabase"; + + const supabase = createClient({ + request: Astro.request, + cookies: Astro.cookies, + }); + + const { data } = await supabase.auth.getUser(); + + if (data?.user) { + return Astro.redirect("/dashboard"); + } + --- + + + + Sign In + + +

Sign In

+ +
+ +
+
+ + +
+
+ + +
+ +
+

+ Don't have an account? Sign up +

+ + + + + ``` + +
+ +
+ + + + + Create a new file at `src/pages/dashboard.astro` to display the authenticated user's information. Use a client-side event listener for the sign-out button: + + + + + + ```astro name=src/pages/dashboard.astro + --- + import { createClient } from "../lib/supabase"; + + const supabase = createClient({ + request: Astro.request, + cookies: Astro.cookies, + }); + + const { data } = await supabase.auth.getUser(); + const user = data?.user; + + if (!user) { + return Astro.redirect("/auth/signin"); + } + --- + + + + Dashboard + + +

Welcome!

+

Email: {user.email}

+

User ID: {user.id}

+ + + + + + + ``` + +
+ +
+ + + + + Start the development server, then navigate to http://localhost:4321/auth/signup to test the authentication. + + + + + + ```bash name=Terminal + npm run dev + ``` + + + + +
+ +## Learn more + +- [Supabase Auth docs](/docs/guides/auth#authentication) for more Supabase authentication methods