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-dom

Import 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

  • PaywallGate inspects resourceUrl (plain fetch)
  • 402 — overlay shows price from gateway accepts
  • User connects wallet → pays → @x402/fetch signs 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 chain
  • strategypreference-first or server-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