Ploy
Ploy
Authentication

Next.js helpers

Read the session in Server Components, Route Handlers, and Server Actions, and protect routes with middleware.

Next.js helpers

@meetploy/nextjs includes server-side helpers for Ploy Auth in the App Router. Pair them with the React components for the client side.

pnpm add @meetploy/nextjs @meetploy/auth-react

Read the user on the server

app/dashboard/page.tsx
import { currentUser } from "@meetploy/nextjs/auth";

export default async function Dashboard() {
	const user = await currentUser();
	return <h1>{user ? `Welcome, ${user.email}` : "Not signed in"}</h1>;
}
HelperReturns
currentUser()The PloyUser, or null
auth(){ userId, user, token }, all null when signed out
protect(options?)The PloyUser; redirects to sign-in when signed out
getSessionToken()The raw session token from the ploy_session cookie or an Authorization: Bearer header
signInUrl(returnTo?)URL of the hosted sign-in page
<SignedIn>, <SignedOut>Server Components that render children by session state

Every helper checks the session against the database through the PLOY_AUTH binding, so signed-out and revoked sessions are rejected immediately. Calls are deduplicated per request.

Require a user

app/settings/page.tsx
import { protect } from "@meetploy/nextjs/auth";

export default async function Settings() {
	const user = await protect({ returnTo: "/settings" });
	return <p>Signed in as {user.email}</p>;
}

protect() redirects to /_ploy/auth/sign-in?redirectTo=/settings. Pass signInUrl: "/login" to use your own page.

Route Handlers and Server Actions

app/api/posts/route.ts
import { getPloyContext } from "@meetploy/nextjs";
import { auth } from "@meetploy/nextjs/auth";

export async function GET() {
	const { userId } = await auth();
	if (!userId) {
		return Response.json({ error: "Unauthorized" }, { status: 401 });
	}
	const { env } = getPloyContext();
	const { results } = await env.DB.prepare(
		"SELECT * FROM posts WHERE user_id = ?",
	)
		.bind(userId)
		.all();
	return Response.json({ posts: results });
}

Protect routes with middleware

middleware.ts
import { authMiddleware } from "@meetploy/nextjs/auth-middleware";

export default authMiddleware({
	protectedRoutes: ["/dashboard", "/settings", /^\/admin/],
});

export const config = {
	matcher: ["/((?!_next|_ploy|.*\\..*).*)"],
};

On Next.js 16, name the file proxy.ts. A string matches the path and everything below it; a RegExp is tested against the pathname. Signed-out visitors are redirected to the hosted sign-in page with redirectTo set to the page they asked for.

Middleware only checks that a session cookie is present; it can't validate it, because the signing secret never leaves Ploy. Always confirm the user in the page or route with currentUser() or protect().

Local development

With initPloyForDev() in next.config, ploy dev provides the PLOY_AUTH binding and points the helpers and React components at the local emulator. See the Next.js auth guide for the full setup.

How is this guide?

Last updated on