Skip to main content

AuthzX + Next.js

Add authorization to your Next.js app in 5 minutes.

Install

npm install @authzx/sdk

Set up the client

Create lib/authzx.ts:

import { AuthzX } from '@authzx/sdk'

export const authzx = new AuthzX({
apiKey: process.env.AUTHZX_API_KEY!,
})

Add your API key to .env.local:

AUTHZX_API_KEY=azx_...

Server-side check (App Router)

In a Server Component or page.tsx:

import { authzx } from '@/lib/authzx'
import { redirect } from 'next/navigation'

export default async function DocumentPage({ params }: { params: { id: string } }) {
const userId = await getCurrentUserId() // your auth logic

const allowed = await authzx.check(
{ id: userId },
'read',
{ id: params.id, type: 'document' }
)

if (!allowed) {
redirect('/unauthorized')
}

return <div>Document content</div>
}

API Route

Create app/api/documents/[id]/route.ts:

import { authzx } from '@/lib/authzx'
import { NextRequest, NextResponse } from 'next/server'

export async function GET(req: NextRequest, { params }: { params: { id: string } }) {
const userId = req.headers.get('x-user-id')
if (!userId) {
return NextResponse.json({ error: 'unauthorized' }, { status: 401 })
}

const allowed = await authzx.check(
{ id: userId },
'read',
{ id: params.id, type: 'document' }
)

if (!allowed) {
return NextResponse.json({ error: 'forbidden' }, { status: 403 })
}

return NextResponse.json({ id: params.id, content: '...' })
}

Conditional UI

Check permissions and show/hide UI elements:

import { authzx } from '@/lib/authzx'

export default async function DocumentActions({ userId, docId }: Props) {
const canEdit = await authzx.check({ id: userId }, 'write', { id: docId, type: 'document' })
const canDelete = await authzx.check({ id: userId }, 'delete', { id: docId, type: 'document' })

return (
<div>
{canEdit && <button>Edit</button>}
{canDelete && <button>Delete</button>}
</div>
)
}

Using the local agent

For lower latency, run the AuthzX Agent and point the SDK to it:

export const authzx = new AuthzX({
baseUrl: process.env.AUTHZX_URL || 'http://localhost:8181',
})

No API key needed when using the agent.

Error handling

import { AuthzXError } from '@authzx/sdk'

try {
await authzx.check(subject, 'read', resource)
} catch (err) {
if (err instanceof AuthzXError && err.isAuthError) {
// Invalid API key — check your .env.local
}
}