Ploy
Ploy
Authentication

React components

Drop-in sign-in, sign-up, and account components for React with @meetploy/auth-react.

React components

@meetploy/auth-react gives React apps ready-made auth UI and hooks. It works with Next.js, Vite, TanStack Start, and any other React setup deployed on Ploy.

pnpm add @meetploy/auth-react

Set up the provider

Wrap your app in AuthProvider. It loads the current user and the project's enabled sign-in methods.

import { AuthProvider } from "@meetploy/auth-react";

export function App({ children }: { children: React.ReactNode }) {
	return <AuthProvider>{children}</AuthProvider>;
}

In Next.js, put it in app/layout.tsx. The components are client components, so they work inside Server Component layouts.

Components

ComponentWhat it renders
SignInFormEvery enabled method: provider buttons, a passkey button, and the email and password form
SignUpFormSign-up with every enabled method, including passkey sign-up and extra metadata fields
UserButtonAn avatar that opens a menu with the user's name and email, Manage account, and Sign out
UserProfileAn account page: profile, connected Google, Apple, and GitHub accounts, passkeys, and sign out
SignedInIts children, only when a user is signed in
SignedOutIts children, only when nobody is signed in

All of them follow your project's sign-in methods, so turning a method on in the dashboard shows it everywhere without a redeploy.

A typical header

import { SignedIn, SignedOut, UserButton } from "@meetploy/auth-react";

export function Header() {
	return (
		<header>
			<SignedOut>
				<a href="/login">Sign in</a>
			</SignedOut>
			<SignedIn>
				<UserButton userProfileUrl="/account" afterSignOutUrl="/" />
			</SignedIn>
		</header>
	);
}

Sign-in and sign-up pages

"use client";

import { SignInForm } from "@meetploy/auth-react";

export default function LoginPage() {
	return (
		<SignInForm
			redirectTo="/dashboard"
			onSignUpClick={() => location.assign("/signup")}
		/>
	);
}

SignUpForm takes the same props plus fields, a list of extra metadata fields such as ["name", "company"].

PropDescription
redirectToNavigate here after success
onSuccess, onErrorCallbacks with the user or the error
onSignUpClick / onSignInClickShow a link to the other form
theme"auto" (default), "light", or "dark"
appearanceColors, radius, and font; see Theming
classNameExtra class on the root element

Account page

"use client";

import { UserProfile } from "@meetploy/auth-react";

export default function AccountPage() {
	return <UserProfile afterSignOutUrl="/" />;
}

Users can connect another provider (when it is enabled), disconnect one, add and remove passkeys, and sign out. Ploy refuses to remove the last way a user can sign in.

Theming

Every component follows the system color scheme by default, and switches to dark mode inside a .dark class (Tailwind's convention). Force a mode with theme="light" or theme="dark".

Change colors, corner radius, and font with appearance, on one component or on AuthProvider for all of them:

<AuthProvider
	appearance={{
		variables: {
			colorPrimary: "#4f46e5",
			colorPrimaryHover: "#4338ca",
			borderRadius: "12px",
			fontFamily: "Inter, sans-serif",
		},
		hideBranding: true,
	}}
>
VariableCSS custom property
colorPrimary--ploy-auth-primary
colorPrimaryHover--ploy-auth-primary-hover
colorPrimaryForeground--ploy-auth-primary-foreground
colorBackground--ploy-auth-background
colorText--ploy-auth-foreground
colorTextSecondary--ploy-auth-muted
colorBorder--ploy-auth-border
colorInputBackground--ploy-auth-input-background
colorInputBorder--ploy-auth-input-border
colorDanger--ploy-auth-danger
borderRadius--ploy-auth-radius
fontFamily--ploy-auth-font-family

appearance values apply in both light and dark mode. For different values per mode, set the custom properties in your own CSS instead:

.ploy-auth-root {
	--ploy-auth-primary: #4f46e5;
}
.dark .ploy-auth-root {
	--ploy-auth-primary: #818cf8;
}

Hooks

useAuth() exposes the state and every action, for building your own UI:

FieldDescription
user, isLoading, isAuthenticatedCurrent session
configEnabled methods from /_ploy/auth/config
redirectErrorploy_auth_error code after a failed social sign-in
signIn, signUpEmail and password
signInWithProvider(provider, { redirectTo })Start Google, Apple, or GitHub sign-in
signInWithPasskey, signUpWithPasskey, addPasskey, listPasskeys, removePasskeyPasskeys
listIdentities, unlinkIdentityLinked provider accounts
signOutRevoke the session

The session lives in an HttpOnly cookie, so there is no token to store or refresh in the browser. Verify the user on the server with the PLOY_AUTH binding or the Next.js helpers.

How is this guide?

Last updated on