@vibelogin/nextjs
v0.1.6
Published
VibeLogin SDK for Next.js — hosted auth with login, signup, magic links, and OAuth
Readme
@vibelogin/nextjs
Next.js SDK for VibeLogin — drop-in authentication for your app.
Getting Started
- Create a VibeLogin account — Sign up free at app.vibelogin.com
- Create a project — Give it a name and note the Project ID, Secret Key, and Publishable Key from the project settings
- Install this SDK in your Next.js app:
npm install @vibelogin/nextjs
# or
bun add @vibelogin/nextjs- Set environment variables — Add to
.env.local:
VIBELOGIN_PROJECT_ID=your-project-uuid
VIBELOGIN_SECRET_KEY=sk_live_xxxxx
NEXT_PUBLIC_VIBELOGIN_PUBLISHABLE_KEY=pk_live_xxxxx # optional, for embedded mode- Follow the Quick Start below to add auth in 3 files.
Starter repo: Clone vibelogin/nextjs-starter for a working example you can run immediately.
Quick Start (Hosted Redirect)
Get auth working in 3 files. Users are redirected to your VibeLogin-hosted login page, then back to your app with a session.
1. Login Button
// app/page.tsx
import { VibeLogin } from "@vibelogin/nextjs/components";
export default function Home() {
return (
<VibeLogin
slug="your-project-slug"
mode="redirect"
redirectAfterLogin="/dashboard"
/>
);
}2. Callback Handler
// app/auth/callback/route.ts
import { createCallbackHandler } from "@vibelogin/nextjs/callback";
export const { GET } = createCallbackHandler({
secretKey: process.env.VIBELOGIN_SECRET_KEY!,
apiUrl: process.env.VIBELOGIN_API_URL,
});3. Read Session
// app/dashboard/page.tsx
import { redirect } from "next/navigation";
import { createHostedServerHelpers } from "@vibelogin/nextjs/server";
const { getSession } = createHostedServerHelpers({
projectId: process.env.VIBELOGIN_PROJECT_ID!,
apiUrl: process.env.VIBELOGIN_API_URL,
});
export default async function Dashboard() {
const session = await getSession();
if (!session) redirect("/");
return <p>User: {session.userId}, Role: {session.role}</p>;
}That's it. getSession() validates the JWT locally via JWKS — no network call needed.
Environment Variables
Add to .env.local:
# Required for all modes
VIBELOGIN_PROJECT_ID=your-project-uuid
# Required for callback handler (redirect mode) and proxy handler
VIBELOGIN_SECRET_KEY=sk_live_xxxxx
# Required for proxy handler (embedded mode / full redirect)
VIBELOGIN_PUBLISHABLE_KEY=pk_live_xxxxx
# Optional — defaults to https://api.vibelogin.com
# VIBELOGIN_API_URL=https://api.vibelogin.com # defaults to thisModes
Mode A: Hosted Redirect
Users are redirected to auth.vibelogin.com to login, then back with a one-time code.
Tier 1: Minimal (3 files)
Only getSession() and hostedAuthMiddleware() work. See Quick Start above.
Tier 2: Full Integration (4 files)
Add a proxy handler to enable currentUser(), VibeAuthProvider, and client hooks:
// app/api/auth/[...all]/route.ts
import { createHostedHandler } from "@vibelogin/nextjs/handler";
const handler = createHostedHandler({
secretKey: process.env.VIBELOGIN_SECRET_KEY!,
publishableKey: process.env.VIBELOGIN_PUBLISHABLE_KEY!,
apiUrl: process.env.VIBELOGIN_API_URL,
});
export const { GET, POST, PATCH, DELETE } = handler;Now you can use:
// Server component
const { currentUser } = createHostedServerHelpers({
projectId: process.env.VIBELOGIN_PROJECT_ID!,
});
const user = await currentUser();
// user = { id, email, name, role, metadata, ... } or null// Client component
"use client";
import { VibeAuthProvider, useUser, useAuth } from "@vibelogin/nextjs/client";
// Wrap your layout:
<VibeAuthProvider basePath="/api/auth">
{children}
</VibeAuthProvider>
// In any client component:
const { user, isLoading } = useUser();
const { signOut, updateProfile, changePassword } = useAuth();Mode B: Embedded Form
Login form renders on your site. Requires the proxy handler.
// app/login/page.tsx
import { VibeLogin } from "@vibelogin/nextjs/components";
export default function Login() {
return (
<VibeLogin
slug="your-project-slug"
mode="embedded"
redirectAfterLogin="/dashboard"
/>
);
}// middleware.ts
import { hostedAuthMiddleware } from "@vibelogin/nextjs/middleware";
export default hostedAuthMiddleware({
projectId: process.env.VIBELOGIN_PROJECT_ID!,
publicRoutes: ["/", "/login", "/signup"],
});
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};Works in embedded mode: sign-in, sign-up, sign-out, profile update, password change, session hydration, route protection.
Not yet available: magic links, password reset, email verification, OAuth (use redirect mode for these).
API Reference
<VibeLogin />
Drop-in auth component with two modes.
import { VibeLogin } from "@vibelogin/nextjs/components";| Prop | Type | Default | Description |
|------|------|---------|-------------|
| slug | string | required | Project's oauthSlug |
| mode | "redirect" \| "embedded" | "redirect" | Auth mode |
| authUrl | string | "https://auth.vibelogin.com" | Hosted login page URL |
| callbackPath | string | "/auth/callback" | Callback route path |
| redirectAfterLogin | string | "/" | Where to go after login |
| onSuccess | (user: any) => void | — | Embedded mode callback |
| label | string | "Sign in with VibeLogin" | Button text |
| as | "link" \| "button" | "button" | Render as link or button |
| className | string | — | CSS class |
| style | CSSProperties | — | Inline styles |
| basePath | string | "/api/auth" | Proxy handler path (embedded) |
createCallbackHandler(config)
Handles the redirect callback — exchanges the auth code for tokens, sets cookies.
import { createCallbackHandler } from "@vibelogin/nextjs/callback";| Config | Type | Default | Description |
|--------|------|---------|-------------|
| secretKey | string | required | Project secret key |
| apiUrl | string | "https://api.vibelogin.com" | API base URL |
| cookiePrefix | string | "vibeauth" | Cookie name prefix |
| accessTokenMaxAge | number | 900 | Access token cookie max-age (seconds) |
| refreshTokenMaxAge | number | 604800 | Refresh token cookie max-age (seconds) |
| cookieDomain | string | — | Cookie domain for cross-subdomain |
| defaultRedirect | string | "/" | Fallback redirect path |
Returns { GET }.
createHostedServerHelpers(config)
Server-side session utilities. Does not take secretKey.
import { createHostedServerHelpers } from "@vibelogin/nextjs/server";| Config | Type | Default | Description |
|--------|------|---------|-------------|
| projectId | string | required | Project UUID (for JWKS) |
| apiUrl | string | "https://api.vibelogin.com" | API base URL |
| basePath | string | "/api/auth" | Proxy handler path |
| cookiePrefix | string | "vibeauth" | Cookie name prefix |
Returns:
getSession()→{ userId, sessionId, role, expiresAt } | null— JWT-only, no network call. Works in Tier 1.currentUser()→{ id, email, name, role, metadata, ... } | null— Calls local proxy. RequirescreateHostedHandler.
createHostedHandler(config)
Full auth proxy handler. Mount at /api/auth/[...all]/route.ts.
import { createHostedHandler } from "@vibelogin/nextjs/handler";| Config | Type | Default | Description |
|--------|------|---------|-------------|
| secretKey | string | required | Project secret key |
| publishableKey | string | required | Project publishable key |
| apiUrl | string | "https://api.vibelogin.com" | API base URL |
| cookiePrefix | string | "vibeauth" | Cookie name prefix |
| accessTokenMaxAge | number | — | Override access token max-age |
| refreshTokenMaxAge | number | — | Override refresh token max-age |
| cookieDomain | string | — | Cookie domain |
Returns { GET, POST, PATCH, DELETE }.
hostedAuthMiddleware(options)
Next.js middleware for JWT-based route protection.
import { hostedAuthMiddleware } from "@vibelogin/nextjs/middleware";| Option | Type | Default | Description |
|--------|------|---------|-------------|
| projectId | string | required | Project UUID |
| publicRoutes | string[] | — | Routes that skip auth (supports :path* wildcards) |
| signInUrl | string | "/login" | Redirect for unauthenticated users |
| cookiePrefix | string | "vibeauth" | Cookie name prefix |
| apiUrl | string | "https://api.vibelogin.com" | API base URL |
validateToken(token, config)
Standalone JWT validation utility.
import { validateToken } from "@vibelogin/nextjs/validate-token";
const payload = await validateToken(accessToken, {
projectId: process.env.VIBELOGIN_PROJECT_ID!,
});
// payload = { sub, sid, role, jti, iss, aud, iat, exp } or nullClient Hooks
import { VibeAuthProvider, useAuth, useUser } from "@vibelogin/nextjs/client";<VibeAuthProvider basePath="/api/auth"> — Wraps your app, provides auth context.
useUser() — Returns { user, isLoading, error }.
useAuth() — Returns:
signOut()— Sign out and clear sessionupdateProfile(data)— Update user profilechangePassword({ currentPassword, newPassword })— Change password
Cookie Configuration
The SDK sets httpOnly cookies on the customer's domain:
| Cookie | Purpose | Default Max-Age |
|--------|---------|-----------------|
| {prefix}_access_token | JWT access token | 15 minutes |
| {prefix}_refresh_token | Refresh token | 7 days |
| vibelogin_state | CSRF state (redirect mode) | Session |
Customize with cookiePrefix (default: "vibeauth") and cookieDomain for cross-subdomain setups.
Security
- CSRF Protection: Redirect mode generates a random state parameter stored in a cookie. The callback handler validates the state match and rejects requests with missing or mismatched state.
- JWT Verification: Tokens are verified using your project's JWKS endpoint (
/v1/jwks/:projectId). Keys are cached automatically. - httpOnly Cookies: Auth tokens are stored in httpOnly, secure, sameSite=lax cookies — not accessible to JavaScript.
- One-Time Auth Codes: The code returned after login is single-use and expires in 60 seconds.
- Server-Side Secrets: The
secretKeyis only used server-side (callback handler, proxy handler) and never exposed to the browser.
License
MIT
