Astro
This guide shows how to integrate gau with Astro 7, using GitHub as an example.
-
Follow the Basic Setup
Section titled “Follow the Basic Setup”Complete the Getting Started guide.
Create your auth instance in
src/server/auth.ts. For a persistent database, follow the Drizzle guide.For GitHub, set the callback URL to
http://localhost:4321/api/auth/callback/githubduring development. -
Configure Astro
Section titled “Configure Astro”Install an Astro server adapter so auth routes can run on each request. For example, with the Node adapter:
astro.config.mjs import { defineConfig } from 'astro/config'import node from '@astrojs/node'export default defineConfig({output: 'server',adapter: node({ mode: 'standalone' }),session: false,})Gau does not require Astro’s session storage. Omit
session: falseif your app otherwise usesAstro.session. -
Set up the API Route
Section titled “Set up the API Route”Export the Astro helpers alongside your auth instance:
src/server/auth.ts import { AstroAuth } from '@rttnd/gau/astro'// After creating your auth instance:export const gau = AstroAuth(auth)Create a catch-all route for the auth endpoints.
src/pages/api/auth/[...gau].ts import { gau } from '../../../server/auth'export const prerender = falseexport const { GET, POST, OPTIONS } = gau -
Add Middleware
Section titled “Add Middleware”Add the Gau middleware to make sessions available in
Astro.localsand refresh the session cookie when needed.src/middleware.ts import { gau } from './server/auth'export const onRequest = gau.onRequestServer code can now call
Astro.locals.getSession(). UsegetServerSession()only when you need account tokens on the server.Add the locals to
src/env.d.tsfor full type safety:src/env.d.ts import type { GauAstroLocals } from '@rttnd/gau/astro'import type { auth } from './server/auth'declare global {namespace App {interface Locals extends GauAstroLocals<typeof auth> {}}} -
Load the Session
Section titled “Load the Session”Read the session in your page. Use a link to sign in and a form to sign out:
src/pages/index.astro ---const { user } = await Astro.locals.getSession()---{user ? (<><p>Welcome, {user.name}!</p><form method="post" action="/api/auth/signout?redirectTo=/" data-astro-reload><button>Sign out</button></form></>) : (<a href="/api/auth/github?redirectTo=/account" data-astro-reload>Sign in with GitHub</a>)} -
Protect a Page
Section titled “Protect a Page”Check the session before rendering the page or loading private data.
src/pages/account.astro ---export const prerender = falseconst { user } = await Astro.locals.getSession()if (!user)return Astro.redirect('/')---<h1>Welcome, {user.name}!</h1>Check the session in each endpoint or action that accesses private data too. Keep personalized pages out of shared route caches.
-
File Structure
Section titled “File Structure”Directorysrc
Directoryserver
- auth.ts
Directorypages
Directoryapi
Directoryauth
- […gau].ts
- account.astro
- index.astro
- env.d.ts
- middleware.ts
- package.json
- astro.config.mjs
-
Next Steps
Section titled “Next Steps”- See the Astro example for a complete app.
- Explore other OAuth Providers.
- Learn about Protected Routes.
Set up the Client
Section titled “Set up the Client”A browser client is optional. Use the vanilla client in browser scripts, or a Gau Solid or Svelte provider inside a hydrated island.
Pass the session from Astro.locals.getSession() to the island to show the signed-in state immediately.
Separate islands do not share component context. To share updates, create one vanilla client in browser code and pass it through the providers’ client prop. Never share a mutable session client between server requests.
For a retained island, pass fresh server session props after navigation. A client-side sign-out only updates subscribed components; navigate afterward to update other server-rendered content.
Static Pages
Section titled “Static Pages”A prerendered page cannot read a visitor’s session at build time. Use an on-demand page for private content, or a server island for a personalized section of a public page. Read the session inside the island’s own request.