A comprehensive Next.js SDK for PersonQL authentication, user management, and Customer Data Platform (CDP) with automatic digital fingerprinting.
While Next.js can use our existing React SDK, this dedicated Next.js SDK provides:
npm install @personql/nextjs
# or
yarn add @personql/nextjs
# or
pnpm add @personql/nextjs
// 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>
);
}
// 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).*)'],
};
// 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>
);
}
// 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>
);
}
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>
);
}
// 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 };
// 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);
});
'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>;
}
# 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
<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'],
},
}}
>
| Feature | React SDK | Next.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 |
Install Next.js SDK
npm install @personql/nextjs
npm uninstall @personql/react
Update Imports
// Before
import { PersonQLProvider, useAuth } from '@personql/react';
// After
import { PersonQLProvider, usePersonQLNext } from '@personql/nextjs';
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!,
});
Update Hooks
// Before - potential hydration issues
const { isAuthenticated } = useAuth();
// After - SSR-safe
const { isAuthenticated, isHydrated } = usePersonQLNext();
if (!isHydrated) return <div>Loading...</div>;
Works seamlessly with all Next.js deployment platforms: