Next.js + Prisma Example
SSR‑safe UI guards with React plus policy‑compiled Prisma filters for multi‑tenant data.
INFO
Next.js is a React framework. Use @authzkit/react
for UI guards in any React app (Next.js, Remix, Vite + React, CRA, Expo). This page focuses on server decisions and Prisma; see React UI Guards to add client‑side guards.
Setup
- Create a Next.js app (TypeScript):
bash
pnpm create next-app@latest my-app --typescript
cd my-app
bash
npm create next-app@latest my-app -- --typescript
cd my-app
bash
yarn create next-app my-app --typescript
cd my-app
bash
bun create next-app@latest my-app --typescript
cd my-app
- Add Prisma and initialize:
bash
pnpm add -D prisma
pnpm add @prisma/client
pnpm prisma init
bash
npm install --save-dev prisma
npm install @prisma/client
npm exec prisma init
bash
yarn add -D prisma
yarn add @prisma/client
yarn prisma init
bash
bun add -d prisma
bun add @prisma/client
bunx prisma init
- Install AuthzKit packages:
bash
pnpm add @authzkit/core
pnpm add @authzkit/prisma-tenant-guard
bash
npm install @authzkit/core
npm install @authzkit/prisma-tenant-guard
bash
yarn add @authzkit/core
yarn add @authzkit/prisma-tenant-guard
bash
bun add @authzkit/core
bun add @authzkit/prisma-tenant-guard
- Attach Tenant Guard to the Prisma client:
ts
// prisma/client.ts
import { PrismaClient } from '@prisma/client'
import { createTenantClient } from '@authzkit/prisma-tenant-guard'
export const prisma = createTenantClient(new PrismaClient(), {
tenantId: 'your-tenant-id',
meta: {
// Your tenant meta configuration
}
})
- Use decisions in a server component or route handler:
tsx
// app/posts/page.tsx
import { definePolicy } from '@authzkit/core'
import { prisma } from '@/prisma/client'
// You need to define your policy first (group rules by action)
const policy = definePolicy({
byAction: {
'post.read': [
{ id: 'allow-members', effect: 'allow', when: ({ subject }) => subject?.role === 'member' }
]
}
})
export default async function PostsPage() {
const subject = { id: 'u1', tenantId: 't1', role: 'member' }
const d = policy.checkDetailed('post.read', { subject, resource: { tenantId: 't1' } })
if (!d.allow) return <p>Not authorized</p>
const posts = await prisma.post.findMany({
// Apply filtering based on decision attributes if needed
where: d.attrs || {}
})
return <pre>{JSON.stringify(posts, null, 2)}</pre>
}
What to look for
- Tri‑state UI guard patterns that render safely with SSR hydration.
- Field masking and query filtering derived from decisions (
select
/where
). - Prisma Tenant Guard blocks unsafe paths and validates tenant isolation.
Troubleshooting
When you change your Prisma schema, re‑generate and validate safety:
bash
pnpm prisma generate
pnpm authzkit-tenant-guard check
bash
npm exec prisma generate
npm exec authzkit-tenant-guard check
bash
yarn prisma generate
yarn authzkit-tenant-guard check
bash
bunx prisma generate
bunx authzkit-tenant-guard check