Skip to main content
StormyCMS

@stormycms/next

Next.js-specific helpers: an all-in-one auth route handler, a server-side session provider, and server actions.

Terminal window
pnpm add @stormycms/next

createNextAuthHandlers(configOrClient?, options?)

Creates GET/POST handlers implementing the complete auth flow. Mount at /api/auth/stormy:

app/api/auth/stormy/route.ts
import { createNextAuthHandlers } from '@stormycms/next';
export const { GET, POST } = createNextAuthHandlers();

Accepts a StormyClientConfig, an existing StormyCMSClient, or nothing (env-var config). The handler responds to a ?action= query param:

ActionBehavior
signinRedirects to the Stormy auth service. Requires provider=github or provider=google. Optional redirectTo is stored in a short-lived stormy_oauth_redirect_to cookie.
sessionReturns the session user as JSON, or 401. Refreshes the sliding stormy_session_token cookie.
siteReturns the current site (by client credentials).
sitesReturns the signed-in user's sites.
signoutDeletes the stormy_session_token cookie and redirects to /login.
(none)OAuth callback: exchanges the token query param for a session, sets the stormy_session_token cookie, deletes the redirect cookie, and redirects to the saved redirectTo or the site URL. If the callback includes an error param, it redirects to /login?error=....

The POST handler currently returns a placeholder response; the real flow is GET-based.

  • Name: stormy_session_token (httpOnly, SameSite=lax, secure in production, path /).
  • Default lifetime: 8 hours (sliding refresh on every session call).
  • Override with options.sessionCookieMaxAgeSeconds or the STORMY_SESSION_COOKIE_MAX_AGE_SECONDS env var.
  • Upstream calls to the Stormy API time out after 5 seconds.

E2E bypass

The official boilerplate wraps the handler to allow test automation. When E2E_ALLOW_COOKIE_BYPASS=true and a cookie named e2e_bypass_auth=true is present, the session action returns a fake user so Playwright tests can run without real OAuth.

StormyServerProvider

Server-component wrapper around StormyProvider from @stormycms/react/stormy. Fetches the session, current site, and site list on the server, then hydrates the client context:

import { StormyServerProvider } from '@stormycms/next';
import { stormyCMSClient } from '~/stormy-cms-client';
<StormyServerProvider client={stormyCMSClient} loginUrl="/login">
{children}
</StormyServerProvider>;

With guard (default true), unauthenticated users are redirected to loginUrl before anything renders. All StormyProvider props (authUrl, siteUrl, sitesUrl, checkThrottleMs, onSessionExpired) pass through.

createServerActions(client)

Server actions for sign-in/sign-up buttons:

'use server';
import { createServerActions } from '@stormycms/next';
import { stormyCMSClient } from '~/stormy-cms-client';
export const { signIn, signUp } = createServerActions(stormyCMSClient);
// signIn('github', { redirectTo: '/dashboard' })

Both redirect the user to the Stormy auth service and preserve redirectTo via the stormy_oauth_redirect_to cookie.

SessionGuard

SessionGuard exists in @stormycms/next/session-guard.tsx but is not exported from the package index. It mirrors the client-side guard logic in StormyProvider (polls authUrl on user activity and redirects on 401). If you need it, import it from the full path or ask the maintainers to add it to the public exports.

Next Steps

Last updated: 7/9/26, 6:42 AM

StormyCMSThe headless CMS where you own the management panel
Community
StormyCMS