You will learn how to:

  • Create a new React application using Next
  • Configure @kobbleio/next SDK
  • Protect your application routes
  • Add permissions and quotas to your application
Pre-requisites: You need to set up your Kobble account before starting this guide.

Example repository

To make your life simpler, we crafted various Next.js examples that you ca find in our Next Examples Repository.

Installation

1

Create your Next application

Scaffold your new Next application using Next Create App.

npx create-next-app@latest

Then, when prompted, choose the options you prefer for your project.

We recommend the following setup:

What is your project named? my-app
Would you like to use TypeScript? Yes
Would you like to use ESLint? Yes
Would you like to use Tailwind CSS? Yes
Would you like to use `src/` directory? Yes
Would you like to use App Router? Yes (mandatory)
Would you like to customize the default import alias (@/*)? Yes
What import alias would you like configured? @/*
It’s mandatory to use App Router to work with the @kobbleio/next SDK.
2

Install @kobbleio/next

npm install @kobbleio/next
3

Setup the middleware

Our auth middleware allows you to protect your routes and handle the authentication flow seamlessly.

Create a middleware.ts file in your project and add the following code:

import { authMiddleware } from '@kobbleio/next/server'

export default authMiddleware({
    publicRoutes: ['/'],
});

export const config = {
    matcher: [
    // exclude internal Next.js routes
    "/((?!.+\\.[\\w]+$|_next).*)",
    // reinclude api routes
    "/(api|trpc)(.*)"
    ]
};

This middleware will automatically expose various routes to handle authentication.

4

Setup the Kobble Provider

To leverage kobble utilities inside client side components, you need to wrap your app with the KobbleProvider component. This is commonly done in the top level layout.tsx file.

Here’s how your layout.tsx file should look like:

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { KobbleProvider } from '@kobbleio/next/server';
import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
    title: "Create Next App",
    description: "Generated by create next app",
};

export default function RootLayout({
    children,
}: Readonly<{
    children: React.ReactNode;
}>) {
    return (
        <html lang="en">
            <body className={inter.className}>
                <KobbleProvider>
                    {children}
                </KobbleProvider>
            </body>
        </html>
    );
}

Note that KobbleProvider itself is a server side component, and as such should not be rendered by a client component directly.

5

Setup the environment variables

At this stage, if you run the project, you will get the following errors:

⨯ Error: Missing NEXT_PUBLIC_KOBBLE_CLIENT_ID

This is because we need to add our Kobble Client ID and Customer Portal Domain to the environment variables.

If you don’t know how to get these variables, it’s covered in our setup guide.

Create a .env file at the root of your project and add the following environment variables.

KOBBLE_CLIENT_SECRET=your-client-secret
NEXT_PUBLIC_KOBBLE_CLIENT_ID=your-client-id
NEXT_PUBLIC_KOBBLE_DOMAIN=your-domain-url
NEXT_PUBLIC_KOBBLE_REDIRECT_URI=http://localhost:3000/callback
KOBBLE_DOMAIN and KOBBLE_CLIENT_ID can be found in the Kobble Application we created earlier. The REDIRECT_URI could be any route of your choice since the domain points to your Next Application.

User authentication

1

Handling user state (client side)

In your client side code you can directly use the useAuth hook and various built-in components to manage your user’s state and permissions.

Here’s a simple example using <SignedIn />, <SignedOut />, <LoginButton />, <LogoutButton /> components:

'use client'

import {
    useAuth,
    SignedIn,
    SignedOut,
    LoginButton,
    LogoutButton,
} from '@kobbleio/next/client'

export default function Home() {
    const { user } = useAuth();

    return (
        <div>
            <SignedIn>
                <p>Welcome, {user?.name}</p>
                <LogoutButton />
            </SignedIn>

            <SignedOut>
                <p>Not authenticated</p>
                <LoginButton />
            </SignedOut>
        </div>
    )
}
2

Handling user state (server side)

On your server code you can leverage @kobbleio/next/server utilities to handle user state and permissions.

import { getAuth } from '@kobbleio/next/server'

export default async function handler(req, res) {
    const { session } = await getAuth();

    if (!session) {
        return res.status(401).json({ error: 'Unauthorized' });
    }

    // An active session was found. User and tokens can be accessed from the session object.
    <!-- YOUR LOGIC HERE -->
    console.log(session.user);
}

Permissions and quotas

1

Managing permissions (client side)

At this stage, you can manage your user’s permissions and quotas client using our <IsAllowed /> and <IsForbidden /> components.

To learn more about permissions and quotas, check out the Kobble documentation.
import {
    IsAllowed,
    IsForbidden,
    SignedIn,
} from '@kobbleio/next/client'

export default function Home() {
    return (
        <div>
            <SignedIn>
                <IsAllowed permission="generate-image">
                    <button>Generate Image</button>
                </IsAllowed>

                <IsForbidden permission="generate-image">
                    <span>You're not allowed to generate images.</span>
                </IsForbidden>
            </SignedIn>
        </div>
    )
}
2

Managing permissions (server side)

import { getKobble } from '@kobbleio/next/server'

export default async function handler(req, res) {
    const { kobble } = await getKobble();

    const isAllowed = await kobble.acl.hasPermission('permission-name');

    <!-- YOUR LOGIC HERE -->
}
3

Managing quotas (client side)

At this stage, you can manage your user’s permissions and quotas client using our <IsAllowed /> and <IsForbidden /> components.

To learn more about permissions and quotas, check out the Kobble documentation.
import {
IsAllowed,
IsForbidden,
SignedIn,
} from '@kobbleio/next/client'

export default function Home() {
return (
    <div>
        <SignedIn>
            <IsAllowed permission="generate-image">
                <button>Generate Image</button>
            </IsAllowed>

            <IsForbidden quota="generated-images">
                <span>You're not allowed to generate images.</span>
            </IsForbidden>
        </SignedIn>
    </div>
)
}
4

Managing quotas (server side)

import { getKobble } from '@kobbleio/next/server'

export default async function handler(req, res) {
    const { kobble } = await getKobble();

    const isAllowed = await kobble.acl.hasRemainingQuota('quota-name');

    <!-- YOUR LOGIC HERE -->
}

Going further

This guide contained the basics to get you started with Kobble in your Next.js application.

However, there are many more features you can leverage to enhance your application.

Find more information in the Kobble Next.js reference.