Skip to main content

@zewstid/nextjs

Official ZewstID SDK for Next.js - OAuth/OIDC authentication with ZewstID.

npm version License: Proprietary

Current Version: v0.9.0 (February 2026)

v0.9.0: Adds Popup Sign-In and Embedded Sign-In components. See Popup Sign-In Guide and Embedded Sign-In Guide.

✨ Features

  • 🔐 OAuth/OIDC - Standard OpenID Connect with ZewstID
  • 🌐 12 Auth Methods - Password, magic links, OTP, WebAuthn, social login, MFA — all on auth.zewstid.com
  • 🔄 Cross-Portal SSO - Automatic SSO via ZewstID session cookies
  • 🎯 Type-Safe - Full TypeScript support
  • 📦 Lightweight - Minimal footprint with tree-shaking
  • 📱 Next.js 14/15 - Full App Router and Pages Router support

🚀 Installation

npm install @zewstid/nextjs next-auth

📖 Quick Start

1. Get Your Credentials

Sign up at developers.zewstid.com and create a new application to get your:

  • Client ID
  • Client Secret

2. Environment Variables

Create a

.env.local
file:

ZEWSTID_CLIENT_ID=your_client_id ZEWSTID_CLIENT_SECRET=your_client_secret NEXTAUTH_SECRET=your_random_secret_min_32_chars NEXTAUTH_URL=http://localhost:3000

3. Create Auth Configuration

App Router (

app/api/auth/[...nextauth]/route.ts
):

import { createZewstIDAuth } from '@zewstid/nextjs'; import NextAuth from 'next-auth'; export const authOptions = createZewstIDAuth({ clientId: process.env.ZEWSTID_CLIENT_ID!, clientSecret: process.env.ZEWSTID_CLIENT_SECRET!, }); const handler = NextAuth(authOptions); export { handler as GET, handler as POST };

4. Wrap Your App

// app/layout.tsx import { ZewstIDProvider } from '@zewstid/nextjs'; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html> <body> <ZewstIDProvider> {children} </ZewstIDProvider> </body> </html> ); }

5. Add Sign In/Out Buttons

'use client'; import { signIn, signOut, useSession } from 'next-auth/react'; export function AuthButtons() { const { data: session } = useSession(); if (!session) { return ( <button onClick={() => signIn('zewstid')}> Sign in with ZewstID </button> ); } return ( <div> <p>Welcome {session.user?.name}!</p> <button onClick={() => signOut()}>Sign Out</button> </div> ); }

🔐 Authentication Flow

  1. User clicks "Sign in with ZewstID"
  2. Browser redirects to
    auth.zewstid.com
  3. User authenticates using any of 12 methods
  4. Browser redirects back with authorization code
  5. NextAuth exchanges code for tokens
  6. Session is created in your app

🛡️ Protecting Routes

Middleware Protection

// middleware.ts import { withZewstIDAuth } from '@zewstid/nextjs/middleware'; export default withZewstIDAuth({ protectedPaths: ['/dashboard', '/settings'], signInPath: '/api/auth/signin', }); export const config = { matcher: ['/dashboard/:path*', '/settings/:path*'], };

Server Component Protection

// app/dashboard/page.tsx import { getServerSession } from 'next-auth'; import { authOptions } from '@/app/api/auth/[...nextauth]/route'; import { redirect } from 'next/navigation'; export default async function DashboardPage() { const session = await getServerSession(authOptions); if (!session) { redirect('/api/auth/signin'); } return <div>Welcome {session.user?.name}!</div>; }

🔑 Role-Based Access Control

import { useRBAC, RBACProvider } from '@zewstid/nextjs'; const rolePermissions = { admin: [{ resource: '*', action: '*' }], editor: [{ resource: 'posts', action: '*' }], viewer: [{ resource: 'posts', action: 'read' }], }; // Wrap your app <RBACProvider clientId="my-app" rolePermissions={rolePermissions}> {children} </RBACProvider> // Use in components function AdminPanel() { const { hasRole } = useRBAC(); if (!hasRole('admin')) { return <p>Access denied</p>; } return <div>Admin Panel</div>; }

🚪 Logout

For proper logout that clears both NextAuth and ZewstID sessions:

// app/api/auth/logout/route.ts import { createLogoutHandler } from '@zewstid/nextjs/handlers'; import { authOptions } from '../[...nextauth]/route'; export const GET = createLogoutHandler(authOptions, { postLogoutRedirectUri: process.env.NEXTAUTH_URL, });
// In your component <a href="/api/auth/logout">Sign Out</a>

📦 API Reference

Main Exports (
@zewstid/nextjs
)

ExportDescription
createZewstIDAuth()
Create NextAuth configuration
ZewstIDProvider
Session provider wrapper
getZewstIDCallbacks()
NextAuth callbacks for token handling
useZewstID()
Hook for auth state
useRBAC()
Hook for role-based access
RBACProvider
RBAC context provider
PopupSignIn
Popup-based sign-in button (guide)
PopupCallback
Popup callback page component
EmbeddedSignIn
Clerk-style inline sign-in form (guide)
UserButton
User avatar dropdown with sign out

Handlers (
@zewstid/nextjs/handlers
)

ExportDescription
createLogoutHandler()
Logout with ZewstID session end
createPostLogoutHandler()
Post-logout redirect handler

Middleware (
@zewstid/nextjs/middleware
)

ExportDescription
withZewstIDAuth()
Middleware for route protection
createClientMiddleware()
Custom middleware creator

🔄 Migrating from v0.7.x to v0.9.0

v0.8.0 removed ROPC-based embedded authentication. v0.9.0 re-introduces embedded auth using new, secure components.

What Was Removed in v0.8.0

// ❌ These no longer work import { createZewstIDHandlers } from '@zewstid/nextjs/handlers'; // REMOVED import { SignIn } from '@zewstid/nextjs'; // Old component removed // ❌ These methods throw errors await client.signInWithPassword(email, password); // Throws await client.verifyMagicLink(token); // Throws await client.verifyOTP(email, code); // Throws

What's New in v0.9.0

// ✅ New components (replace old <SignIn />) import { PopupSignIn, PopupCallback, EmbeddedSignIn, UserButton } from '@zewstid/nextjs/components';

Migration Steps

  1. Remove ROPC handlers: Delete
    app/api/zewstid/[...zewstid]/route.ts
  2. Replace
    <SignIn />
    : Use one of:
    • signIn('zewstid')
      — redirect (simplest)
    • <PopupSignIn />
      — popup window (Auth0 Lock-style)
    • <EmbeddedSignIn />
      — inline form (Clerk-style)
  3. Remove
    enableSSOEstablishment
    : SSO works automatically via ZewstID session
  4. Update logout: Use
    createLogoutHandler()
    for proper session cleanup

🆘 Support

Was this page helpful?

Let us know how we can improve our documentation