Next.js SDK (@nself/next)
Next.js 14+ adapter: SSR auth, middleware, RSC-safe server clients, and React hooks.
@nself/next
The Next.js adapter wraps @nself/client with cookie-based session management, middleware for JWT auto-refresh, and React context hooks.
Install
pnpm add @nself/client @nself/next
Setup in 3 steps
Step 1: Middleware
Create middleware.ts at your Next.js project root:
import { updateSession } from '@nself/next/middleware'
export const middleware = updateSession
export const config = { matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'] }
This auto-refreshes the JWT on every request, 60 seconds before it expires.
Step 2: Root layout
Wrap your app in NselfProvider and pass the server-side session for SSR hydration:
// app/layout.tsx
import { NselfProvider } from '@nself/next/client'
import { createServerClient } from '@nself/next/server'
import { cookies } from 'next/headers'
export default async function RootLayout({ children }) {
const nself = createServerClient(await cookies())
const session = nself.auth.getSession()
return (
<html>
<body>
<NselfProvider
url={process.env.NEXT_PUBLIC_NSELF_URL!}
anonKey={process.env.NEXT_PUBLIC_NSELF_ANON_KEY!}
initialSession={session}
>
{children}
</NselfProvider>
</body>
</html>
)
}
Step 3: Protect routes
// app/dashboard/page.tsx (Server Component)
import { createServerClient } from '@nself/next/server'
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
export default async function Dashboard() {
const nself = createServerClient(await cookies())
const session = nself.auth.getSession()
if (!session) redirect('/login')
const { data } = await nself.graphql.query(GetMessagesDocument)
return <MessageList messages={data?.messages ?? []} />
}
Client components
'use client'
import { useNselfClient, useUser, useSession } from '@nself/next/client'
export function ProfileBadge() {
const { user, loading } = useUser()
if (loading) return <span>Loading...</span>
if (!user) return <a href="/login">Sign in</a>
return <span>{user.email}</span>
}
export function RealtimeMessages() {
const { nself } = useNselfClient()
useEffect(() => {
const channel = nself.realtime
.channel('messages-live')
.on('INSERT', ({ new: msg }) => addMessage(msg))
.subscribe()
return () => channel.unsubscribe()
}, [nself])
// ...
}
Sign in from a Server Action
// app/login/actions.ts
'use server'
import { createServerClient, setSessionCookies } from '@nself/next/server'
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
export async function signIn(formData: FormData) {
const cookieStore = await cookies()
const nself = createServerClient(cookieStore)
const { session, error } = await nself.auth.signIn({
email: formData.get('email') as string,
password: formData.get('password') as string,
})
if (error || !session) return { error: error?.message }
setSessionCookies(cookieStore, session.accessToken, session.refreshToken, session.expiresAt)
redirect('/dashboard')
}
Pages Router support
For the Pages Router, use getServerSideProps:
// pages/dashboard.tsx
import { createServerClient } from '@nself/next/server'
import { parse } from 'cookie'
export async function getServerSideProps({ req, res }) {
const cookies = parse(req.headers.cookie ?? '')
const cookieStore = {
get: (name: string) => (cookies[name] ? { value: cookies[name] } : undefined),
}
const nself = createServerClient(cookieStore)
const session = nself.auth.getSession()
if (!session) return { redirect: { destination: '/login', permanent: false } }
return { props: { user: session.user } }
}
API reference
@nself/next/server
| Export | Signature | Description |
|---|---|---|
createServerClient | (cookies, opts?) => NselfClient | RSC-safe client |
setSessionCookies | (cookies, access, refresh, expiresAt) => void | Persist tokens |
clearSessionCookies | (cookies) => void | Clear on sign-out |
@nself/next/middleware
| Export | Description |
|---|---|
updateSession | Next.js middleware: JWT auto-refresh |
@nself/next/client
| Export | Description |
|---|---|
NselfProvider | Root context provider |
useNselfClient() | { nself, session, user, loading } |
useSession() | { session, loading } |
useUser() | { user, loading } |