Ploy
Ploy
Authentication

React with Vite

Add sign-in to a React single-page app built with Vite and deployed on Ploy.

React with Vite

This guide adds Ploy Auth to a React app built with Vite: drop-in forms in the browser and a worker route that knows who is signed in. The complete code is in examples/vite-react-auth.

1. Configure the project

ploy.yaml
kind: dynamic
build: pnpm build
out: dist
assets:
  binding: ASSETS
  not_found_handling: single-page-application
  run_worker_first:
    - /api/*
    - /_ploy/*
auth:
  binding: AUTH_DB

run_worker_first sends /_ploy/* past the single-page fallback, so the auth endpoints and hosted pages are reachable during local development.

pnpm add @meetploy/auth-react
pnpm add -D @meetploy/cli @meetploy/vite
vite.config.ts
import { ploy } from "@meetploy/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
	plugins: [react(), ...ploy()],
});

2. Wrap the app

src/main.tsx
import { AuthProvider } from "@meetploy/auth-react";
import { createRoot } from "react-dom/client";

import App from "./App";

createRoot(document.getElementById("root")!).render(
	<AuthProvider>
		<App />
	</AuthProvider>,
);

3. Show sign-in or the account

src/App.tsx
import {
	SignedIn,
	SignedOut,
	SignInForm,
	UserButton,
	UserProfile,
} from "@meetploy/auth-react";

export default function App() {
	return (
		<main>
			<header>
				<SignedIn>
					<UserButton afterSignOutUrl="/" />
				</SignedIn>
			</header>
			<SignedOut>
				<SignInForm />
			</SignedOut>
			<SignedIn>
				<UserProfile />
			</SignedIn>
		</main>
	);
}

The forms show whatever sign-in methods are enabled for the project. See React components for every component, prop, and theming option.

4. Protect a worker route

The browser sends the ploy_session cookie with same-origin requests. Verify it in the worker with env.PLOY_AUTH:

worker/index.ts
export default {
	async fetch(request, env) {
		const url = new URL(request.url);
		if (url.pathname === "/api/profile") {
			const token = request.headers
				.get("Cookie")
				?.match(/(?:^|;\s*)ploy_session=([^;]+)/)?.[1];
			const user = token ? await env.PLOY_AUTH.getUser(token) : null;
			if (!user) {
				return Response.json({ error: "Unauthorized" }, { status: 401 });
			}
			return Response.json({ userId: user.id });
		}
		return new Response("Not found", { status: 404 });
	},
} satisfies Ploy;

From React, call it with a plain fetch("/api/profile"). Run ploy types to add PLOY_AUTH to your generated env.d.ts.

5. Run it locally

pnpm ploy dev

ploy dev serves the auth endpoints and hosted pages on your app's own origin and provides env.PLOY_AUTH, backed by a local database. Password sign-in and passkeys work on localhost; add PLOY_AUTH_* credentials to .env to try social sign-in.

Want to skip the forms entirely? Link to /_ploy/auth/sign-in?redirectTo=/ and use the hosted pages instead.

How is this guide?

Last updated on