<ApplicationForm>
Drop-in multi-step camp application widget from @playaos/react — no Tailwind config required.
<ApplicationForm> is a self-contained apply widget from @playaos/react. Drop it into any
React app and it renders the full multi-step camp application, validates each step with the same Zod schema
the PlayaOS portal uses, submits through the API, and shows success and error states.
Unlike the Tailwind-based drop-in components, <ApplicationForm> ships scoped styles injected at runtime —
no Tailwind setup and no stylesheet import in your app.
Installation
npm install @playaos/react @playaos/api-client @tanstack/react-query zod
# or
pnpm add @playaos/react @playaos/api-client @tanstack/react-query zodzod is an optional peer of @playaos/api-client — <ApplicationForm> imports @playaos/api-client/schemas, so it must be installed.
Quick Start
import { createClient } from "@playaos/api-client";
import { ApplicationForm, PlayaOSProvider } from "@playaos/react";
const client = createClient({
baseUrl: "https://your-camp.playaos.app",
apiKey: "pk_live_...",
});
export function Apply() {
return (
<PlayaOSProvider client={client}>
<ApplicationForm
orgId="your-camp"
onSubmitted={(res) => console.log("Application", res.applicationId)}
theme={{ primary: "#b5402b", radius: "12px" }}
/>
</PlayaOSProvider>
);
}The component must be rendered inside a <PlayaOSProvider> so it can reach the configured
API client. On success it calls onSubmitted with { applicationId, status } and renders a confirmation panel.
Props
| Prop | Type | Notes |
|---|---|---|
orgId | string (required) | The org the application belongs to. Rendered as data-org-id; request routing is handled by the client's per-org base URL. |
onSubmitted | (result: ApplicationCreateResponse) => void | Called after a successful submission. |
theme | ApplicationFormTheme | Token overrides, mapped to --paf-* CSS custom properties. |
referralCode | string | Prefills the referral code. |
acknowledgmentContent | ReactNode | Override the step-0 expectations copy with your camp's wording. |
accessToken | string | PlayaOS IdP JWT to submit on behalf of a known profile (otherwise anonymous). |
className | string | Appended to the scoped root element. |
Steps
The wizard walks applicants through six steps, validated independently:
- Acknowledgment — participation expectations (override copy via
acknowledgmentContent). - Contact — name, email, phone, birthday, hometown, optional socials.
- Connection — how they heard about the camp; prior Burning Man attendance.
- Logistics — shelter type and ticket status.
- Build & Strike — availability and skills for setup/teardown.
- About — a short personal statement and agreement to the 10 Principles.
Theming
Styles are scoped under .playaos-af and injected at runtime. Override any token via the theme prop:
<ApplicationForm orgId="your-camp" theme={{ primary: "#2563eb", radius: "14px", fontFamily: "Inter, sans-serif" }} />…or with your own CSS:
.playaos-af {
--paf-primary: #2563eb;
--paf-radius: 14px;
}Available tokens: primary, primaryContrast, fg, muted, bg, surface, border, error, radius, fontFamily.
Bundle size
react, @tanstack/react-query, and @playaos/api-client (with its zod dependency) are peer dependencies
and externalized from the build, so they are not double-shipped. The widget's own code — markup, validation
glue, and the injected scoped stylesheet — is ~7 kB gzipped, well under the 150 kB budget.