@monetize.software/sdk-react
v3.0.0-alpha.2
Published
React bindings for @monetize.software/sdk — Provider, hooks and declarative components. Works with the web SDK and the extension SDK (any drop-in compatible PaywallUI).
Downloads
220
Readme
@monetize.software/sdk-react
React bindings для @monetize.software/sdk — Provider, хуки и декларативные компоненты для пейвола. Работает с web SDK и extension SDK (любой drop-in-совместимый PaywallUI).
- Bundle: < 2 KB gzip (только bindings, никакого UI — он внутри SDK).
- React: >= 18, использует
useSyncExternalStoreдля concurrent-safe чтения снимков. - SSR: безопасно. На сервере хуки отдают
null/{ status: 'loading' }, инстанс PaywallUI создаётся только на клиенте. - TypeScript: полный тип-уровень контракт (
src/contract.ts) — если в основном SDK поедет публичная поверхность, сборка sdk-react падает на этапеtsc.
Установка
pnpm add @monetize.software/sdk-react @monetize.software/sdk reactQuick start
import {
PaywallProvider,
PaywallGate,
PaywallButton,
usePaywallUser
} from '@monetize.software/sdk-react';
function App() {
return (
<PaywallProvider options={{ paywallId: 'YOUR_ID', auth: true }}>
<PaywallGate fallback={<UpgradeCTA />}>
<PremiumFeature />
</PaywallGate>
<PaywallButton>Upgrade</PaywallButton>
</PaywallProvider>
);
}
function UpgradeCTA() {
const user = usePaywallUser();
return <p>Привет, {user?.email ?? 'гость'}! Открой полный доступ.</p>;
}Provider
<PaywallProvider> принимает один из двух пропсов:
// Вариант 1 — Provider сам создаёт инстанс
<PaywallProvider options={{ paywallId, apiOrigin, auth: true }}>
// Вариант 2 — готовый инстанс снаружи (extension / shared / тесты)
import { createPaywallUI } from '@monetize.software/sdk-extension';
const paywall = createPaywallUI({ paywallId });
<PaywallProvider instance={paywall}>Если paywallId динамически меняется, перемонтируй Provider через <PaywallProvider key={paywallId} options={...}> — реактивная пересборка опций намеренно не делается.
Хуки
| Хук | Возвращает | Когда триггерит rerender |
|---|---|---|
| usePaywall() | PaywallUI \| null | смена инстанса (редко) |
| usePaywallState() | { open, view, error } | любое изменение state-машины |
| usePaywallUser() | PaywallUser \| null | event userChange |
| usePaywallAccess(opts?) | { status, result } | userChange / purchase_completed |
| usePaywallPrices() | { prices, loading, error } | bootstrap refresh |
| usePaywallTrial() | TrialStatus \| null | trial_blocked / trial_expired |
| usePaywallVisibility() | VisibilityStatus \| null | ready / visibility_blocked |
| usePaywallEvent(event, handler) | — | подписка с stable-handler-ref |
Все хуки безопасны до mount-а Provider'а (отдают null / loading) — можно использовать в SSR без 'use client'-обёрток на ветке дерева.
Компоненты
<PaywallGate>
Декларативный гейт: loading → fallback → children.
<PaywallGate
loading={<Skeleton />}
fallback={({ open }) => <button onClick={open}>Upgrade</button>}
openOnBlocked={false} // если true — автоматом дёргает paywall.open()
>
<PremiumFeature />
</PaywallGate><PaywallButton> / <PaywallSupportButton>
Сахар над paywall.open(). По умолчанию рендерится как нативный <button> со всеми твоими className/disabled/aria-*. Для кастомного элемента — render-prop:
<PaywallButton render={({ open, ready }) => (
<MyButton onClick={open} disabled={!ready}>Upgrade</MyButton>
)} />mode переключает между open() / openSupport() / openAuth() / openAnonGate():
<PaywallButton mode="support">Need help?</PaywallButton>
<PaywallButton mode="auth">Sign in</PaywallButton>SSR / Next.js
'use client'; // на Provider, не на дерево потомков
import { PaywallProvider } from '@monetize.software/sdk-react';
export function PaywallProviders({ children }) {
return (
<PaywallProvider options={{ paywallId: process.env.NEXT_PUBLIC_PAYWALL_ID! }}>
{children}
</PaywallProvider>
);
}Хуки можно вызывать из server components только при типизированных-null-сценариях (всё равно вернётся null/loading). Рекомендация — выносить хук-логику в client component.
Защита от изменений в SDK
pnpm typecheck проверяет src/contract.ts — там перечислены все точки опоры на public API SDK (методы PaywallUI, поля snapshot'ов, имена событий). Любое разъезжание в ../sdk ловится здесь раньше, чем в проде.
После изменений в SDK обнови dist для типов:
cd ../sdk && pnpm build
cd ../sdk-react && pnpm typecheckРазработка
pnpm install
pnpm dev # → http://localhost:5080/demo/
pnpm typecheck # TS-валидация + контракт
pnpm test # vitest + @testing-library/react
pnpm test:e2e # playwright против демо
pnpm build # ESM + CJS + d.ts → dist/API reference
Полные JSDoc-комментарии на каждый публичный экспорт смотри в исходниках:
src/PaywallProvider.tsx— Provider, lifecyclesrc/hooks/— все хукиsrc/components/— декларативные компонентыsrc/contract.ts— точки опоры на SDK
