Authsome

Next.js Integration

Server sessions, Edge middleware, API proxy, cookie storage, and pre-built pages for Next.js via @authsome/ui-nextjs.

@authsome/ui-nextjs extends the React package with server-side utilities for Next.js. It provides session validation in Server Components, Edge middleware for route protection, an API proxy handler, cookie-based token storage, auto-discovery of enabled auth methods, and pre-built authentication pages.

Installation

npm install @authsome/ui-nextjs @authsome/ui-react @authsome/ui-core @authsome/ui-components

Server-side features

getServerSession

Read and validate the session cookie in Server Components or Route Handlers. Returns a ServerSession with the validated User and sessionToken, or null if there is no valid session.

// app/dashboard/page.tsx
import { getServerSession } from "@authsome/ui-nextjs";
import { redirect } from "next/navigation";

export default async function DashboardPage() {
  const session = await getServerSession({
    baseURL: process.env.AUTHSOME_API_URL!,
  });

  if (!session) {
    redirect("/sign-in");
  }

  return (
    <div>
      <h1>Welcome, {session.user.name}</h1>
      <p>Email: {session.user.email}</p>
    </div>
  );
}

Options

OptionTypeDefaultDescription
baseURLstring--Authsome API URL
cookieNamestring"authsome_session_token"Cookie name for the session token

getClientConfig

Fetches the client configuration from the Authsome backend server-side with ISR caching (5-minute revalidation). The client config describes which authentication methods are enabled (password, social, passkey, MFA, magic link, SSO) so your UI components can auto-configure without manual props.

Pass the result as initialClientConfig to AuthProvider to avoid a redundant client-side fetch on mount.

// app/layout.tsx (Server Component)
import { getClientConfig } from "@authsome/ui-nextjs";
import { Providers } from "./providers";

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const clientConfig = await getClientConfig({
    baseURL: process.env.AUTHSOME_API_URL!,
    publishableKey: process.env.NEXT_PUBLIC_AUTHSOME_KEY,
  });

  return (
    <html lang="en">
      <body>
        <Providers initialClientConfig={clientConfig ?? undefined}>
          {children}
        </Providers>
      </body>
    </html>
  );
}

Options

OptionTypeDefaultDescription
baseURLstring--Authsome API URL
publishableKeystring--Publishable key to identify the app

ClientConfig shape

The returned ClientConfig object describes the enabled authentication methods:

interface ClientConfig {
  version?: string;
  app_id?: string;
  branding?: { app_name?: string; logo_url?: string };
  password?: { enabled: boolean };
  social?: { enabled: boolean; providers: { id: string; name: string }[] };
  passkey?: { enabled: boolean };
  mfa?: { enabled: boolean; methods: string[] };
  magiclink?: { enabled: boolean };
  sso?: { enabled: boolean; connections: { id: string; name: string }[] };
}

createCookieStorage

Creates a TokenStorage implementation backed by document.cookie. Use this in the client-side AuthProvider so that session tokens are stored as cookies, making them accessible to both the Edge middleware and server components.

// app/providers.tsx
"use client";

import { AuthProvider } from "@authsome/ui-nextjs";
import { createCookieStorage } from "@authsome/ui-nextjs";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <AuthProvider
      baseURL={process.env.NEXT_PUBLIC_AUTHSOME_URL!}
      storage={createCookieStorage()}
    >
      {children}
    </AuthProvider>
  );
}
OptionTypeDefaultDescription
pathstring"/"Cookie path
sameSite"strict" | "lax" | "none""lax"SameSite attribute
securebooleantrue in HTTPSSet the Secure flag
maxAgenumber30 days (seconds)Cookie Max-Age in seconds

Middleware

createAuthMiddleware

Creates a Next.js Edge middleware that protects routes behind authentication. Unauthenticated users are redirected to the sign-in page. The middleware validates the session token against the Authsome API on every request.

It also redirects already-authenticated users away from auth pages (sign-in, sign-up) to prevent them from seeing login forms when they are already logged in.

// middleware.ts
import { createAuthMiddleware } from "@authsome/ui-nextjs/middleware";

export default createAuthMiddleware({
  baseURL: process.env.AUTHSOME_API_URL!,
  signInPage: "/sign-in",
  publicPaths: ["/", "/sign-in", "/sign-up", "/forgot-password", "/api/authsome/*"],
  authPaths: ["/sign-in", "/sign-up"],
  afterSignInUrl: "/dashboard",
});

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};

Configuration

OptionTypeDefaultDescription
baseURLstring--Authsome API URL
signInPagestring"/sign-in"Redirect target for unauthenticated users
publicPathsstring[]["/", signInPage]Paths that do not require authentication. Supports glob suffixes with *
cookieNamestring"authsome_session_token"Cookie name to read
authPathsstring[][signInPage, "/sign-up"]Paths that redirect authenticated users away (e.g. sign-in, sign-up pages). Supports glob suffixes
afterSignInUrlstring"/"Where to redirect authenticated users visiting auth pages

The middleware appends a ?redirect= query parameter to the sign-in URL so you can redirect users back after authentication.

Note: Make sure /api/authsome/* is included in publicPaths so the proxy route handler is accessible without authentication.

Proxy route handler

createProxyHandler

Creates a Next.js App Router catch-all route handler that proxies requests from your Next.js app to the Authsome backend API. This is required for social login (OAuth callbacks), magic link verification, and any other flow where the browser needs to communicate with the Authsome API through your app's domain.

The proxy handler:

  • Forwards Authorization and Cookie headers to the backend
  • Proxies request bodies for non-GET/HEAD methods
  • Forwards Set-Cookie response headers back to the browser (essential for session cookies)
  • Parses JSON responses with a text fallback
// app/api/authsome/[...path]/route.ts
import { createProxyHandler } from "@authsome/ui-nextjs/proxy";

const handler = createProxyHandler({
  baseURL: process.env.NEXT_PUBLIC_AUTHSOME_API_URL!,
});

export { handler as GET, handler as POST, handler as PUT, handler as DELETE, handler as PATCH };

This single file replaces any manual proxy implementation. All requests to /api/authsome/* will be forwarded to the corresponding path on your Authsome backend (e.g., /api/authsome/v1/auth/signin proxies to <baseURL>/v1/auth/signin).

Configuration

OptionTypeDefaultDescription
baseURLstring--Base URL of the Authsome backend API

Important: Add /api/authsome/* to your middleware's publicPaths array so the proxy route is accessible without authentication.

Pre-built pages

The package ships pre-built Next.js page components that combine the styled components with routing logic:

PageImport pathDescription
SignInPage@authsome/ui-nextjs/pagesFull-page sign-in with social providers
SignUpPage@authsome/ui-nextjs/pagesFull-page registration
ForgotPasswordPage@authsome/ui-nextjs/pagesRequest password reset
ResetPasswordPage@authsome/ui-nextjs/pagesSet new password from token
MagicLinkPage@authsome/ui-nextjs/pagesPasswordless sign-in
MFAChallengePage@authsome/ui-nextjs/pagesMFA verification
UserProfilePage@authsome/ui-nextjs/pagesProfile management

Using pre-built pages

// app/sign-in/page.tsx
import { SignInPage } from "@authsome/ui-nextjs/pages";

export default function Page() {
  return <SignInPage />;
}
// app/sign-up/page.tsx
import { SignUpPage } from "@authsome/ui-nextjs/pages";

export default function Page() {
  return <SignUpPage />;
}

Full setup (App Router)

1. Environment variables

# .env.local
NEXT_PUBLIC_AUTHSOME_URL=https://api.example.com
AUTHSOME_API_URL=https://api.example.com
NEXT_PUBLIC_AUTHSOME_KEY=pk_live_xxxxx  # Optional: publishable key for auto-discovery

2. Root layout with server-side autoconfig

Pre-fetch the client configuration server-side and pass it to the providers:

// app/layout.tsx
import { getClientConfig } from "@authsome/ui-nextjs";
import { Providers } from "./providers";

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const clientConfig = await getClientConfig({
    baseURL: process.env.AUTHSOME_API_URL!,
    publishableKey: process.env.NEXT_PUBLIC_AUTHSOME_KEY,
  });

  return (
    <html lang="en">
      <body>
        <Providers initialClientConfig={clientConfig ?? undefined}>
          {children}
        </Providers>
      </body>
    </html>
  );
}

3. Client providers

// app/providers.tsx
"use client";

import { AuthProvider, createCookieStorage } from "@authsome/ui-nextjs";
import type { ClientConfig } from "@authsome/ui-nextjs";

export function Providers({
  children,
  initialClientConfig,
}: {
  children: React.ReactNode;
  initialClientConfig?: ClientConfig;
}) {
  return (
    <AuthProvider
      baseURL={process.env.NEXT_PUBLIC_AUTHSOME_URL!}
      storage={createCookieStorage()}
      publishableKey={process.env.NEXT_PUBLIC_AUTHSOME_KEY}
      initialClientConfig={initialClientConfig}
    >
      {children}
    </AuthProvider>
  );
}

4. Proxy route handler

// app/api/authsome/[...path]/route.ts
import { createProxyHandler } from "@authsome/ui-nextjs/proxy";

const handler = createProxyHandler({
  baseURL: process.env.NEXT_PUBLIC_AUTHSOME_URL!,
});

export { handler as GET, handler as POST, handler as PUT, handler as DELETE, handler as PATCH };

5. Middleware

// middleware.ts
import { createAuthMiddleware } from "@authsome/ui-nextjs/middleware";

export default createAuthMiddleware({
  baseURL: process.env.AUTHSOME_API_URL!,
  signInPage: "/sign-in",
  publicPaths: ["/", "/sign-in", "/sign-up", "/forgot-password", "/api/authsome/*"],
  afterSignInUrl: "/dashboard",
});

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};

6. Protected server page

// app/dashboard/page.tsx
import { getServerSession } from "@authsome/ui-nextjs";
import { redirect } from "next/navigation";

export default async function DashboardPage() {
  const session = await getServerSession({
    baseURL: process.env.AUTHSOME_API_URL!,
  });

  if (!session) redirect("/sign-in");

  return <h1>Dashboard for {session.user.name}</h1>;
}

Pages Router support

For the Pages Router, use the same hooks and components inside _app.tsx:

// pages/_app.tsx
import { AuthProvider } from "@authsome/ui-nextjs";
import { createCookieStorage } from "@authsome/ui-nextjs";
import type { AppProps } from "next/app";

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <AuthProvider
      baseURL={process.env.NEXT_PUBLIC_AUTHSOME_URL!}
      storage={createCookieStorage()}
    >
      <Component {...pageProps} />
    </AuthProvider>
  );
}

For server-side session validation in getServerSideProps, read the cookie manually and validate against the API:

// pages/dashboard.tsx
import type { GetServerSideProps } from "next";

export const getServerSideProps: GetServerSideProps = async (ctx) => {
  const token = ctx.req.cookies["authsome_session_token"];
  if (!token) {
    return { redirect: { destination: "/sign-in", permanent: false } };
  }

  const res = await fetch(`${process.env.AUTHSOME_API_URL}/v1/auth/me`, {
    headers: { Authorization: `Bearer ${token}` },
  });

  if (!res.ok) {
    return { redirect: { destination: "/sign-in", permanent: false } };
  }

  const user = await res.json();
  return { props: { user } };
};

Re-exported APIs

@authsome/ui-nextjs re-exports everything from @authsome/ui-react for convenience, so you only need one import source in your Next.js application:

import {
  AuthProvider,
  useAuth,
  useUser,
  useOrganizations,
  useSessionToken,
  useClientConfig,
  SignInForm,
  SignUpForm,
  MFAChallengeForm,
  AuthGuard,
} from "@authsome/ui-nextjs";

// Types
import type {
  AuthState,
  ClientConfig,
  User,
  Session,
  Organization,
  TokenStorage,
  ServerSession,
} from "@authsome/ui-nextjs";

On this page