Quickstart
Next.js
Sign-in in five minutes with @authio/nextjs and @authio/react.
This guide ends with a Next.js 15 app where sign-in works against your Authio project. We assume you already have a project and an sk_live_ key — if not, see Provisioning a project.
1. Install
pnpm add @authio/nextjs @authio/react2. Configure environment
Add the following to .env.local. The publishable key is safe to expose to the browser; the secret key stays server-side.
AUTHIO_PUBLISHABLE_KEY=pk_live_...
AUTHIO_SECRET_KEY=sk_live_...
NEXT_PUBLIC_AUTHIO_API_URL=https://api.authio.com3. Add the middleware
Drop this in middleware.ts at your project root. It verifies the Authio session JWT against the cached JWKS at the edge, with no round-trip to auth-core.
// middleware.ts
import { authMiddleware } from "@authio/nextjs";
export default authMiddleware({
apiUrl: process.env.NEXT_PUBLIC_AUTHIO_API_URL,
publicRoutes: ["/", "/pricing", "/sign-in"],
});
export const config = {
matcher: ["/((?!_next|.*\\..*).*)"],
};4. Wrap the app in AuthioProvider
// app/layout.tsx
import { AuthioProvider } from "@authio/react";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<AuthioProvider
publishableKey={process.env.NEXT_PUBLIC_AUTHIO_PUBLISHABLE_KEY!}
apiUrl={process.env.NEXT_PUBLIC_AUTHIO_API_URL}
>
{children}
</AuthioProvider>
</body>
</html>
);
}5. Drop in the sign-in surface
// app/sign-in/page.tsx
import { SignIn } from "@authio/react";
export default function SignInPage() {
return <SignIn redirectAfter="/dashboard" />;
}6. Read the session in a Server Component
// app/dashboard/page.tsx
import { auth } from "@authio/nextjs/server";
export default async function DashboardPage() {
const { userId, orgId, role } = await auth();
if (!userId) {
return <p>Please sign in.</p>;
}
return (
<div>
<p>User {userId}</p>
<p>Active organization {orgId ?? "(none selected)"}</p>
<p>Role {role ?? "n/a"}</p>
</div>
);
}orgId is null after sign-in, the user has multiple memberships and hasn’t picked one yet. Render an <OrganizationSwitcher /> from @authio/react to let them choose — switching is a no-re-auth call to POST /v1/sessions/switch-org.What you just did
Your Next.js app now verifies real Authio JWTs at the Edge runtime using cached JWKS, exposes a typed auth() helper to Server Components, and renders the Authio-hosted login experience with one component. From here, see One user, many orgs for the multi-org session model.