ReactComponents
Protected
Show children when signed in; otherwise render a fallback.
Overview
Protected shows children when the user is signed in. When signed out it renders fallback (or nothing). While loading it renders null. Optionally pass onUnauthenticated to run a side effect once when the user is not signed in—for example redirecting to login.
Show complements Protected when you need when="email-verified" or a shared loading fallback without wiring fallback on every gate.
Preview
Interactive preview requires JavaScript.
Install
npx @simpleauthjs/react add sessionProps
| Name | Type | Required | Description |
|---|---|---|---|
children | ReactNode | Yes | Content for authenticated users. |
fallback | ReactNode | No | Shown when not signed in (after loading completes). |
onUnauthenticated | () => void | No | Runs at most once when the session is known and the user is signed out. |
Usage
"use client"
import type { ReactNode } from "react"
import { Protected } from "@/components/simpleauth"
import { useRouter } from "next/navigation"
export function DashboardShell({ children }: { children: ReactNode }) {
const router = useRouter()
return (
<Protected fallback={<p>Please sign in.</p>} onUnauthenticated={() => router.replace("/login")}>
{children}
</Protected>
)
}Source
Protected is part of the session feature. The scaffolded sources are shown here together with the other session gates.
components/simpleauth/hooks/use-current-user.ts
"use client"
import { useCallback, useEffect, useState } from "react"
import { SimpleAuthError, type MeResponse } from "@simpleauthjs/core"
import { useSimpleAuthClient } from "../provider"
type UseCurrentUserOptions = {
autoLoad?: boolean
}
function getErrorMessage(error: unknown) {
if (error instanceof SimpleAuthError) {
return error.message
}
if (error instanceof Error) {
return error.message
}
return "Unable to fetch current user."
}
export function useCurrentUser(options: UseCurrentUserOptions = {}) {
const { autoLoad = true } = options
const auth = useSimpleAuthClient()
const [isLoading, setIsLoading] = useState(Boolean(autoLoad))
const [error, setError] = useState<string | null>(null)
const [data, setData] = useState<MeResponse | null>(null)
const refresh = useCallback(async () => {
setIsLoading(true)
setError(null)
try {
const response = await auth.me()
setData(response)
return response
} catch (requestError) {
setData(null)
setError(getErrorMessage(requestError))
throw requestError
} finally {
setIsLoading(false)
}
}, [auth])
useEffect(() => {
if (!autoLoad) {
return
}
refresh().catch(() => {})
}, [autoLoad, refresh])
return {
refresh,
data,
error,
isError: Boolean(error),
isLoading,
}
}