Skip to main content

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

ExportSignatureDescription
createServerClient(cookies, opts?) => NselfClientRSC-safe client
setSessionCookies(cookies, access, refresh, expiresAt) => voidPersist tokens
clearSessionCookies(cookies) => voidClear on sign-out

@nself/next/middleware

ExportDescription
updateSessionNext.js middleware: JWT auto-refresh

@nself/next/client

ExportDescription
NselfProviderRoot context provider
useNselfClient(){ nself, session, user, loading }
useSession(){ session, loading }
useUser(){ user, loading }