Next.js
For Next.js App Router apps, the standard FFDB pattern is a client-side provider wrapper at the root plus session-aware hooks inside client components.
Why this setup is recommended
- Name
Centralized client lifecycle- Description
One provider in the root layout keeps client creation and cleanup predictable.
- Name
Framework-aligned rendering- Description
Hooks run in client components where auth/session and browser state are available.
- Name
Template parity- Description
Matches the FFDB Next.js overlay generated by
ffdb-cli init.
Environment setup
Add your FFDB app URL to .env.local:
NEXT_PUBLIC_FFDB_API_URL="https://your-app.ffdb.forever-frameworks.com"
Keep privileged credentials out of NEXT_PUBLIC_* variables. Public env keys are bundled for browser use.
Provider component
Create providers.tsx as a client component:
'use client'
import { FFDBProvider } from 'ffdb-client/react'
import type { Database } from '@/types/ffdb.types'
export function AppProviders({ children }: { children: React.ReactNode }) {
return (
<FFDBProvider<Database>
options={{
config: {
apiUrl: process.env.NEXT_PUBLIC_FFDB_API_URL,
},
}}
>
{children}
</FFDBProvider>
)
}
Root layout wiring
Wrap your app tree in the provider from layout:
import { AppProviders } from '@/providers'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<AppProviders>{children}</AppProviders>
</body>
</html>
)
}
End-to-end page flow
Use auth + query hooks in client pages or components:
'use client'
import { useAuth, useFFDB, useQuery } from 'ffdb-client/react'
export default function DashboardPage() {
const ffdb = useFFDB()
const auth = useAuth()
const session = auth.useSession()
const { data, isLoading } = useQuery(
(db) =>
db
.selectFrom('user')
.select(['id', 'email'])
.where('id', '=', session.data?.user?.id ?? ''),
{
enabled: Boolean(session.data?.user?.id),
deps: [session.data?.user?.id],
},
)
if (ffdb.isLoading || session.isPending) return <p>Loading...</p>
return isLoading ? <p>Fetching user...</p> : <pre>{JSON.stringify(data, null, 2)}</pre>
}
Practical guidance
- Keep provider and data hooks in client components.
- Use
session.data?.user?.iddrivenenabledflags to avoid premature queries. - Prefer typed query-builder calls for most reads and writes.
- Add sync status UI if offline mode is enabled.