Skip to main content
The @insforge/nextjs package provides authentication for Next.js applications using hosted auth pages. When users sign in, they’re redirected to your InsForge backend’s login page, then returned to your app after authentication—no UI code required.
Want to build custom login pages instead? See Custom Auth Pages.

Quick Start

Step 1: Create New Next.js Project (Required)

npm install @insforge/nextjs@latest

Step 2: Set Environment Variables

.env.local
NEXT_PUBLIC_INSFORGE_BASE_URL=https://your-app.region.insforge.app
NEXT_PUBLIC_INSFORGE_ANON_KEY=your-anon-key-here

Step 3: 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 4: 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 5: Create InsforgeProvider Component

// app/providers.tsx
'use client';
import { InsforgeBrowserProvider, type InitialAuthState } from '@insforge/nextjs';
import { insforge } from '@/lib/insforge';

export function InsforgeProvider({ children }: { children: React.ReactNode }) {
  return (
    <InsforgeBrowserProvider client={insforge} afterSignInUrl="/dashboard">
      {children}
    </InsforgeBrowserProvider>
  );
}

Step 6: Add InsforgeProvider to Root Layout

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

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>
          <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.profile.name}</p>
      <img src={user.profile.avatar_url} alt="Avatar" />
    </div>
  );
}
Returns:
  • user - User object with id, email, profile
  • user.profile - User profile object with name, avatar_url, and other custom fields
  • 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 { token } = await auth();

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

    // Create InsForge SDK client with user's token for authenticated access
    const insforge = createClient({
      baseUrl: process.env.NEXT_PUBLIC_INSFORGE_BASE_URL || 'https://your-app.region.insforge.app',
      edgeFunctionToken: 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 });
  }
}
Returns:
  • user - User object with id, email, profile
  • userId - User ID
  • token - User’s access token