Skip to main content
The @insforge/nextjs package provides zero-configuration authentication for Next.js applications. Authentication pages are hosted on your backend by default—no UI code needed.

Quick Start

Step 1: Install Package and Set Environment Variables

npm install @insforge/nextjs@latest
.env.local
NEXT_PUBLIC_INSFORGE_BASE_URL=https://your-app.region.insforge.app

Step 2: Add Middleware

Create middleware to protect routes:
middleware.ts
import { InsforgeMiddleware } from '@insforge/nextjs/middleware';

export default InsforgeMiddleware({
  baseUrl: process.env.NEXT_PUBLIC_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app', // Replace with your InsForge backend URL
  publicRoutes: ['/'],
});

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
  ],
};

Step 3: Create API Route

Create an API route to enable server-side rendering (SSR) and cookie-based authentication:
app/api/auth/route.ts
import { createAuthRouteHandlers } from '@insforge/nextjs/api';

const handlers = createAuthRouteHandlers({
  baseUrl: process.env.NEXT_PUBLIC_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app', // Replace with your InsForge backend URL
});

export const POST = handlers.POST;
export const GET = handlers.GET;
export const DELETE = handlers.DELETE;
Why? This route syncs auth tokens to HTTP-only cookies for server-side middleware.

Step 4: Add InsforgeProvider

Wrap your application with the InsforgeProvider in your root layout:
app/layout.tsx
import {
  InsforgeProvider,
  SignedIn,
  SignedOut,
  SignInButton,
  SignUpButton,
  UserButton,
} from '@insforge/nextjs';

export const metadata: Metadata = {
  title: 'InsForge Next.js Quickstart',
  description: 'Generated by create next app',
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <InsforgeProvider
          baseUrl={
            process.env.NEXT_PUBLIC_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app' // Replace with your InsForge backend URL
          }
        >
          <nav>
            <SignedOut>
              <SignInButton />
              <SignUpButton />
            </SignedOut>

            <SignedIn>
              <UserButton />
            </SignedIn>
          </nav>
          {children}
        </InsforgeProvider>
      </body>
    </html>
  );
}
Preventing FOUC: The CSS import in your root layout ensures styles are loaded during server-side rendering, preventing flash of unstyled content (FOUC). Without this import, components may briefly appear unstyled when the page first loads.
That’s it! When users click “Sign In”, they’ll be redirected to your backend’s auth page automatically.

Next Steps

Client-side Hooks

useAuth()

Access authentication state in client side:
'use client';
import { useAuth } from '@insforge/nextjs';

function LoginButton() {
  const { isSignedIn, isLoaded } = useAuth();

  if (!isLoaded) return <div>Loading...</div>;

  return <div>{isSignedIn ? 'Welcome!' : 'Sign In'}</div>;
}
Returns:
  • isSignedIn - Boolean auth state
  • isLoaded - Boolean loading state

useUser()

Access current user data in client side:
'use client';
import { useUser } from '@insforge/nextjs';

function UserProfile() {
  const { user, isLoaded } = useUser();

  if (!isLoaded) return <div>Loading...</div>;
  if (!user) return <div>Not signed in</div>;

  return (
    <div>
      <p>Id: {user.id}</p>
      <p>Email: {user.email}</p>
      <p>Name: {user.name}</p>
      <img src={user.avatarUrl} alt="Avatar" />
    </div>
  );
}
Returns:
  • user - User object with id, email, name, avatarUrl
  • isLoaded - Boolean loading state

Server side functions

auth

Access current user data and access token in server side:
import { auth } from '@insforge/nextjs/server';
import { createClient } from '@insforge/sdk';

export async function POST(request: NextRequest) {
  try {
    // Authenticate the request and get user info
    const { user, userId, token } = await auth();

    // Parse request body to get the prompt
    const { prompt } = await request.json();

    // Create InsForge SDK
    const insforge = createClient({
      baseUrl: process.env.NEXT_PUBLIC_INSFORGE_BASE_URL || "https://your-app.region.insforge.app",
      anonKey: token
    });

    // Request for AI response
    const completion = await insforge.ai.chat.completions.create({
      model: 'anthropic/claude-3.5-haiku',
      messages: [
        {
          role: 'user',
          content: prompt,
        },
      ],
    });

    const generatedResponse = completion.choices[0].message.content.trim();

    // Return success response
    return NextResponse.json(
      {
        success: true,
        data: generatedResponse,
      },
      { status: 201 }
    );

  } catch (error) {
    console.error(error);
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  }
}