@saasifier/nextjs
v0.1.1
Published
Next.js middleware and route-handler bindings for SaaSify tenant resolution.
Readme
@saasifier/nextjs
Next.js middleware and route-handler bindings for SaaSify tenant resolution.
Installation
npm install @saasifier/nextjsOverview
Next.js middleware and the route handler it targets can run as separate invocations (notably on the Edge runtime), so context bound with AsyncLocalStorage in middleware doesn't automatically reach the handler. @saasifier/nextjs bridges that gap: saasify.middleware() resolves the tenant/organization/user/role for an incoming request and forwards the result as request headers, and withSaaSContext() reads those headers back out on the other side and rebinds @saasifier/core's context store before invoking your handler. Together they make saas.context() work correctly across the middleware boundary.
Usage
// middleware.ts
import { saasify } from "@saasifier/nextjs";
import { saas } from "@/lib/saasify";
import { authAdapter } from "@/lib/auth";
export const middleware = saasify.middleware({
saas,
auth: authAdapter,
strategy: "subdomain",
baseDomain: "example.com"
});
export const config = {
matcher: ["/((?!_next|favicon.ico).*)"]
};// app/api/projects/route.ts
import { withSaaSContext } from "@saasifier/nextjs";
import { saas } from "@/lib/saasify";
export const GET = withSaaSContext(saas, async (request) => {
const projects = await saas.entitlements.require("projects", () => listProjects());
return Response.json(projects);
});API Reference
saasify.middleware(options)(alias forcreateSaaSifyMiddleware) — builds theexport const middleware = ...entry point. Options:saas: SaaS— the@saasifier/coreinstance.auth: AuthAdapter<NextRequest>— the app's auth adapter.strategy: TenantResolutionStrategy— how to resolve the tenant from the request (e.g. subdomain, header, path).baseDomain?: string— required for subdomain-based strategies.tenantHeaderName?: string— override the header name used for header-based resolution.
Resolves tenant context, forwards it as request headers (see
SAASIFY_HEADERS), and returnsNextResponse.next(). On failure, returns a JSON error response with the appropriate status: 401 (UnauthorizedError), 403 (ForbiddenError), 404 (TenantNotFoundError), or 400 (any otherSaaSError).withSaaSContext(saas, handler)— wraps an App Router route handler. ReadsSAASIFY_HEADERSoff the incoming request, binds them intosaas.contextStore, and invokeshandler(request, context)within that scope. ThrowsConfigurationErrorif the headers are missing — meaning the route was reached without going throughsaasify.middleware()'s matcher.SAASIFY_HEADERS— the header names used to carry resolved context across the middleware → handler boundary:x-saasify-tenant-id,x-saasify-organization-id,x-saasify-user-id,x-saasify-role.
