Read session and user data in your Astro app with Clerk
Clerk provides helpers that you can use to access the active session and user data in your Astro application.
Server-side
The auth()
and currentUser()
locals are Astro-specific helpers that you can use inside of your Astro components and endpoints.
- The
auth()
local returns theAuth
object of the currently active user. - The
currentUser()
local returns theBackend User
object of the currently active user. This is helpful if you want to render user information, like their first and last name, directly from the server. Under the hood,currentUser()
uses theclerkClient
wrapper to make a call to the Backend API. This does count towards the Backend API request rate limit. This also usesfetch()
so it is automatically deduped per request.
The following example demonstrates how to protect a page from unauthenticated users and access the current user's information.
---
// Get the userId from auth() -- if null, the user is not signed in
const { userId } = Astro.locals.auth()
// Protect the route by checking if the user is signed in
if (!userId) {
return Astro.redirect('/login')
}
// Get the Backend User object when you need access to the user's information
const user = await Astro.locals.currentUser()
---
<!-- Use `user` to render user details or create UI elements -->
<div>Welcome, {user.firstName}!</div>
export async function GET({ locals }) {
// Get the userId from auth() -- if null, the user is not signed in
const { userId } = locals.auth()
// Protect the route by checking if the user is signed in
if (!userId) {
return new Response('Unauthorized', { status: 401 })
}
// Get the Backend User object when you need access to the user's information
const user = await locals.currentUser()
// Add your Route Handler's logic with the returned `user` object
return new Response(JSON.stringify(user))
}
Retrieve data from external sources
Clerk provides integrations with a number of popular databases.
To retrieve a token from a JWT template and fetch data from an external source, use the getToken()
method from the auth()
local.
export async function GET({ locals }) {
// Get the userId and getToken() from auth()
const { userId, getToken } = locals.auth()
// Protect the route by checking if the user is signed in
if (!userId) {
return new Response('Unauthorized', { status: 401 })
}
// Use `getToken()` to get a token from the JWT template
const token = await getToken({ template: 'supabase' })
// Fetch data from Supabase and return it
const data = { supabaseData: 'Hello World' }
return new Response(JSON.stringify(data))
}
Client-side
Clerk Astro provides a set of useful stores that give you access to many important objects, such as the Clerk
, User
, and Session
object.
$authStore
The following example demonstrates how to use the $authStore
to access the current auth state. It uses userId
to detect if the user is signed in.
import { useStore } from '@nanostores/react'
import { $authStore } from '@clerk/astro/client'
export default function ExternalData() {
const { userId } = useStore($authStore)
if (userId === undefined) {
// Handle loading state however you like
return <div>Loading...</div>
}
if (userId === null) {
// Handle signed out state however you like
return <div>Sign in to view this page</div>
}
return <div>...</div>
}
<script setup>
import { useStore } from '@nanostores/vue'
import { $authStore } from '@clerk/astro/client'
const auth = useStore($authStore)
</script>
<template>
<div v-if="auth.userId === undefined">Loading...</div>
<div v-else-if="auth.userId === null">Sign in to view this page</div>
<div v-else>...</div>
</template>
<script>
// The $ prefix is reserved in Svelte for its own reactivity system.
// Alias the imports to avoid conflicts.
import { $authStore as auth } from '@clerk/astro/client'
</script>
{#if $auth.userId === undefined}
<div>Loading...</div>
{:else if $auth.userId === null}
<div>Sign in to view this page</div>
{:else}
<div>...</div>
{/if}
The following example demonstrates how to use the $userStore
to access the User
object. It returns undefined
while Clerk is still loading and null
if the user is not signed in.
For more information, see the User
reference.
import { useStore } from '@nanostores/react'
import { $userStore } from '@clerk/astro/client'
export default function User() {
const user = useStore($userStore)
if (user === undefined) {
// Handle loading state however you like
return null
}
if (user === null) {
return <div>Not signed in</div>
}
return <div>Hello {user.fullName}!</div>
}
<script setup>
import { useStore } from '@nanostores/vue'
import { $userStore } from '@clerk/astro/client'
const user = useStore($userStore)
</script>
<template>
<div v-if="user === undefined">
<!-- Handle loading state however you like -->
</div>
<div v-else-if="user === null">Not signed in</div>
<div v-else>Hello {{ user.fullName }}!</div>
</template>
<script>
// The $ prefix is reserved in Svelte for its own reactivity system.
// Alias the imports to avoid conflicts.
import { $userStore as user } from '@clerk/astro/client'
</script>
{#if $user === undefined}
<!-- Handle loading state however you like -->
{:else if $user === null}
<div>Not signed in</div>
{:else}
<div>Hello {$user.fullName}!</div>
{/if}
Feedback
Last updated on