Skip to content

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

  1. 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
  1. 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
  1. 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
  1. 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
  }
})
  1. 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