<RiftProvider>
Root of the SDK runtime. Provides the cross-cutting context every
SDK hook and component reads — API base URLs, locale, theming
tokens, behavioral callbacks, transport overrides, optional auth.
Mount once near the top of the embedded surface; nest <RiftEvent>
inside for per-event scope.
Import
import { RiftProvider } from "@feelrift/react";
Basic usage
import { RiftProvider } from "@feelrift/react";
export function App({ children }) {
return <RiftProvider locale="es-MX">{children}</RiftProvider>;
}
Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
apiBaseUrl | string | No | https://api.feelrift.com | API host for every SDK request. Override for staging or self-hosted Rift deployments. |
altchaBaseUrl | string | No | https://altcha.feelrift.com | Altcha challenge endpoint. Independent of apiBaseUrl because the challenge endpoint runs on a separate origin. |
locale | string | No | undefined | BCP 47 preferred locale (e.g. "es-MX"). Negotiated against the event's locales.supported by useLocale(). |
strings | Record<string, string> | No | undefined | Per-key string overrides; looked up before the bundled en / es tables. See Internationalization. |
appearance | Appearance | No | undefined | Typed mirror of the --rift-* CSS custom properties. Written onto the provider's root element on mount and on every change. |
theme | "light" | "dark" | No | "light" | Theme variant. "dark" writes data-theme="dark" on the wrapper, activating the SDK's neutral dark token variant. See theme below. |
on | RiftCallbacks | No | undefined | Behavioral callbacks fired on SDK state transitions. See on below for the full list. |
auth | AuthConfig | No | undefined | Opt-in attendee authentication. When set, the SDK mounts the auth context and exposes useSession(). |
tokenStorage | "memory" | "session" | "local" | No | "memory" | Where to persist the OIDC user. "memory" (default) loses tokens on full reload but the silent renewal restores them; "session" survives same-tab reloads; "local" survives across tabs/sessions with the largest XSS exposure. |
children | ReactNode | Yes | — | Subtree that consumes the SDK context. |
apiBaseUrl
Set explicitly for staging or multi-environment deployments where
the same SDK build hits different hosts at runtime. Defaults to
https://api.feelrift.com.
<RiftProvider apiBaseUrl="https://api.staging.feelrift.com">
{children}
</RiftProvider>
altchaBaseUrl
The Altcha challenge endpoint runs on a separate origin from the
API; this prop is its own slot rather than a path on apiBaseUrl.
locale
The SDK ships en and es locale tables. useLocale() negotiates
the active locale by:
- Reading this prop.
- Falling back to the event's
config.locales.default. - Falling back to
en.
For locales beyond en / es, pass per-key overrides via
strings or extend the bundled tables.
strings
Overrides looked up before the bundled locale tables. Useful for one-off label tweaks across the embed:
<RiftProvider
strings={{
"checkout.confirm": "Pagar ahora",
"reservation.reserve": "Apartar boletos",
}}
>
{children}
</RiftProvider>
For larger sets, prefer extending the bundled STRINGS_BY_LOCALE
table — both surfaces are merged the same way at lookup time.
appearance
Typed mirror of the SDK's CSS tokens. Each key maps 1:1 to a
--rift-* custom property by camelCase → kebab-case (colorPrimary
→ --rift-color-primary). Values are written onto the root element
via applyAppearance() at mount and on every prop change.
<RiftProvider
appearance={{
variables: {
colorPrimary: "#0066ff",
radiusMd: "8px",
fontFamily: "Inter, system-ui, sans-serif",
},
}}
>
{children}
</RiftProvider>
CSS tokens remain the canonical source — consumers can override with
plain CSS targeting [data-rift-root] and skip this prop entirely.
theme
Opts in to the SDK's neutral dark token variant by writing
data-theme="dark" onto the [data-rift-root] wrapper. The
matching CSS overrides every
--rift-color-* token; the rest (radius, spacing, typography)
stays the same.
<RiftProvider theme="dark">{children}</RiftProvider>
The dark palette is neutral, not branded — the SDK ships
generic dark surface colors. Layer brand-specific colors on top
via appearance or plain CSS:
<RiftProvider
theme="dark"
appearance={{ variables: { colorPrimary: "#E61919" } }}
>
{children}
</RiftProvider>
The theme prop is purely convenience — consumers driving theme
state from a parent element (e.g. <html data-theme="dark">) can
omit the prop entirely. The dark token variant matches both
[data-rift-root][data-theme="dark"] AND
[data-theme="dark"] [data-rift-root], so an ancestor's attribute
activates it without prop plumbing.
Note The SDK's wrapper does NOT paint
color,background-color,font-family, orfont-sizeon itself — tokens set values on SDK component classes, and everything outside the SDK's own components inherits the consumer's host styling normally.
on
Behavioral callbacks fired on SDK state transitions. Each is optional; SDK components render reasonable defaults when a callback isn't supplied.
| Callback | Payload | Fires when |
|---|---|---|
reservationCreated | (reservation: ActualReservation) => void | A reservation succeeds. |
reservationExpired | () => void | The countdown reaches 00:00. |
reservationPriceChanged | ({ oldTotal, newTotal }) => void | The server's reservation total differs from the estimate the UI displayed. |
checkoutWindowClosed | () => void | Checkout fails with code: "checkout_window_closed". |
paymentSucceeded | (orderId, orderStatusToken) => void | A paid confirmPayment resolves OK, or a free order completes immediately. |
paymentFailed | (error: RiftApiError | StripeError) => void | Server-side checkout or Stripe-side confirmPayment fails. |
signedIn | () => void | Anonymous session transitions to authenticated. |
signedOut | () => void | signOut() clears the local session. |
error | (error: RiftApiError) => void | Catch-all — every RiftApiError the SDK surfaces. |
<RiftProvider
on={{
paymentSucceeded: (orderId) => router.push(`/thanks?o=${orderId}`),
paymentFailed: (err) => Sentry.captureException(err),
error: (err) => Sentry.captureMessage(`Rift: ${err.code}`),
}}
>
{children}
</RiftProvider>
auth
Opt-in attendee authentication. When omitted, every flow that
doesn't require an authenticated attendee (availability,
reservation, anonymous checkout) keeps working unchanged. When set,
the SDK mounts the auth context and exposes useSession() (with
signIn / signOut actions), useAuthCallback(), and
useAttendeeOrders().
tokenStorage
Picks where the OIDC user (access token + expiry) lives:
"memory"(default) — least durable, least XSS exposure. Tokens vanish on full reload; the auth context restores them via silent renewal when asilentRedirectUriis configured."session"— survives same-tab reloads; cleared when the tab closes."local"— survives across tabs and full browser sessions with the largest XSS exposure (any script on the origin can read it).
<RiftProvider auth={authConfig} tokenStorage="session">
{children}
</RiftProvider>
Render output
Renders a single <div data-rift-root=""> wrapper. The
data-rift-root attribute is the CSS scope that isolates the SDK's
custom properties from the host page — pages can target it directly:
[data-rift-root] {
--rift-color-primary: #ff6600;
}
The wrapper is display: block by default; override via the
appearance prop or external CSS if a different layout is needed.
Behavior
- Provider context. Provides the SDK runtime context to its subtree — every SDK hook and component reads through this provider.
- Persistent-state hydration. Rehydrates persisted state (reservation token, order id) in a post-mount effect, so the first server render matches the first client render. See Server-side rendering.
- Appearance application. Writes
appearance.variablesto the root element as--rift-*CSS custom properties on mount and on everyappearanceprop change. - Auth mounting. When
authis set, wrapschildrenin<AuthProvider>. Otherwise renderschildrendirectly with no extra wrapper. - Multiple providers. Multiple
<RiftProvider>instances on the same page are supported but each must scope its own subtree. Persisted state (reservation, config cache) is per-provider — two providers will not share a reservation token.
Examples
Themed embed with callbacks
import { RiftEvent, RiftProvider } from "@feelrift/react";
<RiftProvider
locale="es-MX"
appearance={{
variables: {
colorPrimary: "#0066ff",
colorPrimaryForeground: "#ffffff",
radiusMd: "8px",
},
}}
on={{
paymentSucceeded: (orderId) => router.push(`/thanks?o=${orderId}`),
paymentFailed: (err) => Sentry.captureException(err),
}}
>
<RiftEvent eventId="evt_summerfest_2026">{/* event-scoped UI */}</RiftEvent>
</RiftProvider>;
Staging override
<RiftProvider
apiBaseUrl="https://api.staging.feelrift.com"
altchaBaseUrl="https://altcha.staging.feelrift.com"
>
{children}
</RiftProvider>
With opt-in auth + sessionStorage persistence
<RiftProvider
auth={{
clientId: "rift_app_abc123",
authorizeUrl: "https://auth.feelrift.com/oauth/authorize",
tokenUrl: "https://auth.feelrift.com/oauth/token",
redirectUri: "https://your.site/auth/callback",
silentRedirectUri: "https://your.site/auth/silent-callback",
}}
tokenStorage={
typeof window !== "undefined" ? window.sessionStorage : undefined
}
>
{children}
</RiftProvider>
Related
RiftEvent— event scope inside the provider.- Installation — framework-specific placement.
- Server-side rendering — how the provider stays hydration-safe.