@motherbase/ssr wraps @motherbase/client with the cookie plumbing needed by Next.js. Its root barrel, packages/ssr/src/index.ts, exports createBrowserClient, createServerClient, and updateSession, plus selected client types.
Exported API
| Export | Signature | Intended runtime |
|---|---|---|
createBrowserClient | (url, key?, options?) => MotherbaseClient | Client Components and browser modules |
createServerClient | (url, key, { cookies, ...clientOptions }) => MotherbaseClient | Server Components, Route Handlers, and Server Actions |
updateSession | (request, url, key?, { fetch? }?) => Promise<NextResponse> | Next.js middleware |
The barrel also re-exports the MotherbaseClient, Session, User, ClientOptions, CookieMethods, CookieToSet, and CookieOptions types from @motherbase/client.
Browser client
createBrowserClient calls the base createClient and defaults storage to cookieStorage(). Passing a custom ClientOptions.storage overrides that default. Source: packages/ssr/src/browser.ts.
'use client'
import { createBrowserClient } from '@motherbase/ssr'
export const motherbase = createBrowserClient(
process.env.NEXT_PUBLIC_MOTHERBASE_URL!,
process.env.NEXT_PUBLIC_MOTHERBASE_ANON_KEY,
)The default browser cookie is readable by JavaScript so the server can receive the serialized session on the next request. Its client defaults come from packages/client/src/cookie.ts: name motherbase.session, path /, SameSite=lax, and Secure enabled.
The default cookie is not HttpOnly because browser auth code must update it. Treat the serialized bearer session as sensitive and keep the application protected against script injection.
Server client
createServerClient removes storage from the accepted options and always installs serverCookieStorage(cookies). All other ClientOptions, including fetch, headers, autoRefresh, and realtimeIoFactory, are forwarded. Source: packages/ssr/src/server.ts.
A reusable Next.js helper:
import { cookies } from 'next/headers'
import { createServerClient } from '@motherbase/ssr'
import type { CookieToSet } from '@motherbase/ssr'
export async function createMotherbaseServerClient() {
const cookieStore = await cookies()
return createServerClient(
process.env.NEXT_PUBLIC_MOTHERBASE_URL!,
process.env.NEXT_PUBLIC_MOTHERBASE_ANON_KEY,
{
cookies: {
getAll: () => cookieStore.getAll(),
setAll: (cookiesToSet: CookieToSet[]) => {
try {
for (const { name, value, options } of cookiesToSet) {
cookieStore.set(name, value, options)
}
} catch {
// Server Components cannot write cookies.
// Middleware refreshes the session cookie instead.
}
},
},
},
)
}Use it in a Server Component:
import { createMotherbaseServerClient } from '@/lib/motherbase/server'
export default async function ProductsPage() {
const client = await createMotherbaseServerClient()
const { data: products, error } = await client
.from<{ id: string; name: string }>('products')
.select('id,name')
if (error) return <p>{error.message}</p>
return <pre>{JSON.stringify(products, null, 2)}</pre>
}serverCookieStorage reads all cookies, selects motherbase.session, decodes its JSON, and returns null for missing or malformed data. Writes are batched through setAll; signing out writes an empty cookie with maxAge: 0. Source: packages/client/src/cookie.ts.
A Server Component can read cookies but cannot persist a refreshed or cleared session. The wrapper deliberately allows setAll to be guarded with try/catch; updateSession owns the response-cookie write during navigation.
Middleware refresh
updateSession in packages/ssr/src/middleware.ts creates a server client from NextRequest.cookies, calls client.auth.refreshSession(), and returns a NextResponse.
import type { NextRequest } from 'next/server'
import { updateSession } from '@motherbase/ssr'
export function middleware(request: NextRequest) {
return updateSession(
request,
process.env.NEXT_PUBLIC_MOTHERBASE_URL!,
process.env.NEXT_PUBLIC_MOTHERBASE_ANON_KEY,
)
}When the client writes cookies, the helper:
- updates
request.cookies; - recreates
NextResponse.next({ request })so downstream code sees the new request cookie; - writes the same cookies and their options onto the response.
refreshSession() revalidates the existing Better Auth bearer session. A valid session refreshes the stored user and emits TOKEN_REFRESHED. An invalid session clears the cookie. A network failure is caught and navigation continues with the existing session.
Return the NextResponse produced by updateSession. Replacing it with a new response drops the refreshed or cleared Set-Cookie values.
Framework adapter contract
The package has no hard dependency on next/headers. Framework integration is expressed through CookieMethods:
interface CookieMethods {
getAll(): { name: string; value: string }[]
setAll(cookies: CookieToSet[]): void
}That makes createServerClient usable anywhere a framework can provide batch cookie reads and writes. Only updateSession imports NextRequest and NextResponse directly. The Next.js peer range is >=14 in packages/ssr/package.json.
Related
@motherbase/client— the client these helpers wrap.- Framework quickstarts — the same cookie contract wired into Nuxt, SvelteKit, and others.
- Auth — session lifetimes and the methods a session can come from.