PersonQL Next.js SDK

A comprehensive Next.js SDK for PersonQL authentication, user management, and Customer Data Platform (CDP) with automatic digital fingerprinting.

Why a Dedicated Next.js SDK?

While Next.js can use our existing React SDK, this dedicated Next.js SDK provides:

Automatic SSR/Hydration Handling

Built-in Route Protection

Server Components Support

Advanced Session Management

Installation

npm install @personql/nextjs
# or
yarn add @personql/nextjs
# or
pnpm add @personql/nextjs

Quick Start

Basic Setup

// app/layout.tsx
import { PersonQLProvider } from '@personql/nextjs';
 
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <PersonQLProvider
          apiKey={process.env.NEXT_PUBLIC_PERSONQL_API_KEY!}
        >
          {children}
        </PersonQLProvider>
      </body>
    </html>
  );
}

Automatic Route Protection

// middleware.ts
import { createAuthMiddleware } from '@personql/nextjs';
 
export const middleware = createAuthMiddleware({
  apiKey: process.env.PERSONQL_API_KEY!,
  publicRoutes: ['/', '/about', '/contact'],
  authRoutes: ['/login', '/signup'],
});
 
export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

Server Components

// app/profile/page.tsx
import { getServerUser } from '@personql/nextjs';
import { redirect } from 'next/navigation';
 
export default async function ProfilePage() {
  const user = await getServerUser();
 
  if (!user) {
    redirect('/login');
  }
 
  return (
    <div>
      <h1>Welcome, {user.name}!</h1>
      <p>Email: {user.email}</p>
    </div>
  );
}

Client Components

// components/UserProfile.tsx
'use client';
import { usePersonQLNext } from '@personql/nextjs';
 
export function UserProfile() {
  const { user, isAuthenticated, isHydrated, trackEvent } = usePersonQLNext();
 
  if (!isHydrated) {
    return <div>Loading...</div>;
  }
 
  const handleProfileUpdate = async () => {
    await trackEvent('Profile Updated', { userId: user?.id });
  };
 
  return (
    <div>
      {isAuthenticated ? (
        <div>
          <h2>Hello, {user?.name}</h2>
          <button onClick={handleProfileUpdate}>Update Profile</button>
        </div>
      ) : (
        <div>Please log in</div>
      )}
    </div>
  );
}

Key Features

1. SSR-Safe Authentication

import { usePersonQLNext } from '@personql/nextjs';
 
function MyComponent() {
  const { user, isAuthenticated, isHydrated } = usePersonQLNext();
 
  // Prevents hydration mismatches
  if (!isHydrated) {
    return <div>Loading...</div>;
  }
 
  return (
    <div>
      {isAuthenticated ? `Welcome ${user.name}` : 'Please log in'}
    </div>
  );
}

2. API Route Helpers

// app/api/auth/[...personql]/route.ts
import { createAuthHandler } from '@personql/nextjs';
 
const handler = createAuthHandler({
  apiKey: process.env.PERSONQL_API_KEY!,
  baseUrl: process.env.PERSONQL_BASE_URL!,
});
 
export { handler as GET, handler as POST };

3. Protected API Routes

// app/api/profile/route.ts
import { withAuth } from '@personql/nextjs';
 
export const GET = withAuth(async (request, { user }) => {
  // User is guaranteed to be authenticated
  const profile = await getUserProfile(user.id);
  return Response.json(profile);
});

4. Automatic Analytics

'use client';
import { usePersonQLNext } from '@personql/nextjs';
 
export default function ProductPage({ product }) {
  const { trackEvent, trackPageView } = usePersonQLNext();
 
  useEffect(() => {
    // Automatic fingerprinting and page tracking
    trackPageView(`Product: ${product.name}`);
  }, [product]);
 
  return <div>Product details...</div>;
}

Configuration

Environment Variables

# Public (client-side)
NEXT_PUBLIC_PERSONQL_API_KEY=your_api_key
NEXT_PUBLIC_PERSONQL_BASE_URL=https://app.personql.com
 
# Private (server-side)
PERSONQL_API_KEY=your_server_api_key
PERSONQL_BASE_URL=https://app.personql.com

Advanced Configuration

<PersonQLProvider
  apiKey={process.env.NEXT_PUBLIC_PERSONQL_API_KEY!}
  baseUrl={process.env.NEXT_PUBLIC_PERSONQL_BASE_URL!}
  config={{
    cdp: {
      enabled: true,
      database: 'nextjs_analytics',
      autoTracking: true,
      debug: process.env.NODE_ENV === 'development',
    },
    session: {
      cookieName: 'personql_session',
      maxAge: 60 * 60 * 24, // 24 hours
      secure: process.env.NODE_ENV === 'production',
    },
    auth: {
      redirectTo: '/login',
      afterAuthRedirect: '/dashboard',
      publicRoutes: ['/', '/about', '/contact'],
    },
  }}
>

Comparison with React SDK

FeatureReact SDKNext.js SDK
Basic Auth
SSR Support⚠️ Manual✅ Automatic
Route Protection❌ Manual✅ Middleware
Server Components✅ Native
Token Refresh⚠️ Manual✅ Automatic
Session Sync✅ Unified
Edge Runtime✅ Supported

Migration Guide

From React SDK

  1. Install Next.js SDK

    npm install @personql/nextjs
    npm uninstall @personql/react
  2. Update Imports

    // Before
    import { PersonQLProvider, useAuth } from '@personql/react';
     
    // After
    import { PersonQLProvider, usePersonQLNext } from '@personql/nextjs';
  3. Add Middleware (Optional)

    // middleware.ts - New capability!
    import { createAuthMiddleware } from '@personql/nextjs';
     
    export const middleware = createAuthMiddleware({
      apiKey: process.env.PERSONQL_API_KEY!,
      baseUrl: process.env.PERSONQL_BASE_URL!,
    });
  4. Update Hooks

    // Before - potential hydration issues
    const { isAuthenticated } = useAuth();
     
    // After - SSR-safe
    const { isAuthenticated, isHydrated } = usePersonQLNext();
     
    if (!isHydrated) return <div>Loading...</div>;

Deployment

Works seamlessly with all Next.js deployment platforms:

Next Steps

Support