Next.js Quickstart

Integrate Nebutra with your Next.js 16 App Router project in under 5 minutes.

Prerequisites

  • Node.js 22+
  • A Nebutra account with an OPC license (free)
  • An existing Next.js 16 project, or create one:
npx create-next-app@latest my-app --typescript --tailwind --app
cd my-app

Step 1: Install the SDK

npm install @nebutra/sdk
pnpm add @nebutra/sdk
yarn add @nebutra/sdk

Step 2: Configure environment variables

Create a .env.local file at your project root:

# From your Nebutra dashboard → Settings → API Keys
NEBUTRA_API_KEY=nbk_live_xxxxxxxxxxxxxxxxxxxx
NEBUTRA_ORG_ID=org_xxxxxxxxxxxxxxxxxxxx

# Public key — safe to expose to the browser
NEXT_PUBLIC_NEBUTRA_ORG_ID=org_xxxxxxxxxxxxxxxxxxxx

Never commit .env.local to source control. Add it to .gitignore.

Step 3: Initialize the client

Create a shared Nebutra client:

import { createClient } from "@nebutra/sdk";

export const nebutra = createClient({
  apiKey: process.env.NEBUTRA_API_KEY!,
  orgId: process.env.NEBUTRA_ORG_ID!,
});

Step 4: Protect a route with authentication

Add auth to a Server Component using the Nebutra proxy (Next.js 16+ uses proxy.ts instead of middleware.ts):

import { withNebutraAuth } from "@nebutra/sdk/next";

export default withNebutraAuth({
  publicRoutes: ["/", "/sign-in", "/sign-up"],
});

export const config = {
  matcher: ["/((?!_next|favicon.ico).*)"],
};

Step 5: Read the current user in a Server Component

import { getAuth } from "@nebutra/sdk/next/server";

export default async function DashboardPage() {
  const { user, org } = await getAuth();

  if (!user) {
    redirect("/sign-in");
  }

  return (
    <div>
      <h1>Welcome, {user.firstName}</h1>
      <p>Organization: {org.name}</p>
      <p>Plan: {org.plan}</p>
    </div>
  );
}

Step 6: Make your first API call

import { NextResponse } from "next/server";
import { nebutra } from "@/lib/nebutra";
import { getAuth } from "@nebutra/sdk/next/server";

export async function GET() {
  const { org } = await getAuth();

  const projects = await nebutra.projects.list({
    orgId: org.id,
    limit: 20,
  });

  return NextResponse.json(projects);
}

Step 7: Check permissions before an action

"use server";
import { requirePermission } from "@nebutra/sdk/next/server";
import { nebutra } from "@/lib/nebutra";

export async function deleteProject(projectId: string) {
  // Throws 403 if user lacks the `project:delete` scope
  await requirePermission("project:delete");

  await nebutra.projects.delete(projectId);
}

You're ready

How is this guide?

Edit on GitHub

Last updated on

On this page