React paywall — Getting started
Install the package, point PaywallGate at a gateway URL you configured in the dashboard, and import default styles (or go fully custom — see Theming).
Install
pnpm add @axlabs/x402-react-paywall @x402/fetch @x402/evm viem react react-domImport styles
import "@axlabs/x402-react-paywall/styles.css"Skip this only if you use appearance.unstyled and supply classes for every slot.
Minimal example
import "@axlabs/x402-react-paywall/styles.css";
import { PaywallProvider, PaywallGate } from "@axlabs/x402-react-paywall";
export function ArticlePage() {
return (
<PaywallProvider
policy={{
preferredNetworks: "eip155:84532",
allowedAssets: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
}}
rpc={{ defaultUrl: "https://sepolia.base.org" }}
>
<PaywallGate
resourceUrl="https://your-gateway.example.com/v1/article"
title="Unlock full article"
description="One micropayment via x402 on your gateway."
>
<p>Free preview paragraph…</p>
</PaywallGate>
</PaywallProvider>
);
}Flow
PaywallGateinspectsresourceUrl(plain fetch)- 402 — overlay shows price from gateway
accepts - User connects wallet → pays →
@x402/fetchsigns and retries - 200 — paid body replaces the teaser
Gateway + policy
Create the paid route in the Ax402 dashboard first (gateway wrap). policy on PaywallProvider must allow the network and asset your endpoint advertises (match facilitator /supported networks).
Buyer policy fields
preferredNetworks— e.g.eip155:84532(Base Sepolia)allowedAssets— USDC contract on that chainstrategy—preference-firstorserver-order
CORS (local dev)
Browsers block cross-origin 402 without Access-Control-Allow-Origin. Proxy the gateway through your dev server (see ax402-paywall-demo/demo/vite.config.ts) or host the SPA on the gateway origin.
Staging echo demo uses /echo/get?test=1 proxied to echo.staging.ax402.io.
Headless signing
<PaywallProvider privateKey={process.env.AX402_EVM_PRIVATE_KEY} policy={…} />Never commit private keys. Wallet UI is skipped.
Try the demo
cd ax402-paywall-demo && make demo