Skip to main content

React Components (@nowramp/form)

The @nowramp/form package provides ready-to-use React components for crypto on/off-ramp checkout. It handles currency selection, quote comparison, wallet input, and provider checkout — all within your app, no iframe needed.

Installation

npm install @nowramp/form
# or
yarn add @nowramp/form
# or
pnpm add @nowramp/form
@nowramp/form has peer dependencies on react and react-dom (18+). The @nowramp/sdk package is bundled automatically.

Quick Start

import { RampForm } from '@nowramp/form';

function BuyCrypto() {
  return (
    <RampForm
      projectId="your_project_id"
      apiUrl="https://api.nowramp.com"
      onComplete={(tx) => console.log('Done!', tx.orderId)}
    />
  );
}

RampForm Component

The main component that renders the complete checkout form with currency selection, quote comparison, wallet input, and provider checkout.

Basic Usage (Partner Dashboard Pattern)

This is the minimal setup used in partner dashboard integrations:
<RampForm
  projectId={projectId}
  apiUrl={process.env.NEXT_PUBLIC_API_URL}
  customerId={externalUserId}
  theme={theme}
  borderColor={theme === 'dark' ? '#333333' : '#e2e8f0'}
  borderRadius="10px"
  defaultFiatAmount="250"
/>

Full Branding (Hosted Checkout Pattern)

For hosted checkout flows with complete brand customization:
<RampForm
  projectId={config.projectId}
  apiUrl="https://api.nowramp.com"
  flowType="buy"
  customerId={customerId}
  theme="dark"
  accentColor={branding.accentColor}
  bgColor={branding.bgDarkest}
  surfaceColor={branding.bgMedium}
  inputBgColor={branding.bgLight}
  textColor={branding.textPrimary}
  textSecondaryColor={branding.textSecondary}
  textMutedColor={branding.textMuted}
  successColor={branding.accentColor}
  borderColor="#222222"
  borderRadius="10px"
  showFlowToggle={false}
  showThemeToggle={false}
  defaultFiatCurrency="USD"
  defaultFiatAmount="100"
  defaultCryptoCurrency="ETH"
  defaultNetwork="ethereum"
  defaultWalletAddress="0x742d35Cc..."
  fieldLocks={{
    destinationAddress: { locked: true, value: '0x742d35Cc...' },
    destinationCurrency: { locked: true, value: 'ETH' },
  }}
  onDone={() => router.push('/success')}
  onError={(err) => setError(err.message)}
/>

Props Reference

Core Props

PropTypeDefaultDescription
projectIdstringRequiredYour NowRamp project ID
apiUrlstringhttps://api.nowramp.comAPI base URL
flowType'buy' | 'sell''buy'Buy crypto or sell crypto
customerIdstringExternal customer ID
brandIdstringBrand/config slug identifier

Default Values

PropTypeDefaultDescription
defaultFiatCurrencystring'USD'Initial fiat currency
defaultCryptoCurrencystringInitial crypto currency
defaultNetworkstringInitial blockchain network
defaultFiatAmountstringInitial fiat amount
defaultCryptoAmountstringInitial crypto amount (for sell)
defaultWalletAddressstringPre-filled wallet address
defaultGatewaystringPre-selected gateway ID

Theme & Styling

PropTypeDefaultDescription
theme'light' | 'dark''light'Color theme
skinIdstringSkin preset ID
accentColorstringPrimary/accent color (hex)
bgColorstringMain background color (hex)
bgImagestringBackground image URL
surfaceColorstringCard/surface background (hex)
inputBgColorstringInput/pill background (hex)
textColorstringPrimary text color (hex)
textSecondaryColorstringSecondary/label text (hex)
textMutedColorstringMuted text color (hex)
successColorstringSuccess indicator color (hex)
borderColorstringBorder color (hex)
borderRadiusstringBorder radius (CSS value, e.g., '10px')

UI Controls

PropTypeDefaultDescription
showFlowTogglebooleantrueShow Buy/Sell toggle tabs
showSettingsbooleantrueShow settings menu
showThemeTogglebooleantrueShow dark/light mode toggle
showEmailbooleanfalseShow email input field
requireEmailbooleanfalseMake email required
autoRedirectbooleanAuto-redirect for redirect-based checkouts
rateRefreshIntervalnumberQuote refresh interval (seconds)
statusPollIntervalnumber5000Order status poll interval (ms)

Display Customization

PropTypeDescription
explorerUrlstringBlock explorer URL pattern
doneButtonTextstringCustom done button label
submitButtonTextstringCustom submit button label
supportEmailstringSupport email for error screen
assetBaseUrlstringCDN base URL for static assets

Field Locks

PropTypeDescription
fieldLocksFieldLocksConfigLock specific fields to prevent user modification
<RampForm
  fieldLocks={{
    destinationAddress: { locked: true, value: '0x742d35Cc...' },
    destinationCurrency: { locked: true, value: 'ETH' },
    sourceAmount: { locked: false, min: 50, max: 5000 },
  }}
/>

Callbacks

PropTypeDescription
onComplete(tx: Transaction) => voidCalled when transaction completes
onError(err: Error) => voidCalled on error
onDone() => voidCalled when user clicks done button

RampProvider + useRamp

For full control over the UI, use RampProvider for state management and build your own components.

RampProvider

Wraps your custom UI with configuration, API state, and form management.
import { RampProvider, useRamp } from '@nowramp/form';

function App() {
  return (
    <RampProvider
      projectId="your_project_id"
      apiUrl="https://api.nowramp.com"
      flowType="buy"
      customerId="user_123"
      onComplete={(tx) => console.log('Done!', tx)}
    >
      <CustomCheckoutUI />
    </RampProvider>
  );
}

useRamp Hook

Access the full ramp context within a RampProvider.
function CustomCheckoutUI() {
  const {
    // Configuration
    config,           // OnrampSupported | null
    configLoading,    // boolean
    apiConfig,        // { apiUrl, projectId }

    // Form state
    state,            // RampFormState
    dispatch,         // React.Dispatch<RampAction>

    // Quotes
    quotes,           // QuotesResponse | null
    quotesLoading,    // boolean
    fetchQuotes,      // () => void

    // Order
    order,            // CheckoutIntent | null
    orderLoading,     // boolean
    createOrder,      // () => Promise<void>

    // Transaction status
    orderStatus,      // Transaction | null
    orderStatusLoading,

    // Navigation
    goToStep,         // (step: RampStep) => void
    goBack,           // () => void
    canProceed,       // boolean

    // Validation
    amountError,      // string | null
    fieldLocks,       // FieldLocksConfig | null
  } = useRamp();

  if (configLoading) return <div>Loading...</div>;

  return (
    <div>
      <p>Selected: {state.fiatAmount} {state.fiatCurrency}</p>
      <p>Quotes: {quotes?.quotes.length ?? 0} available</p>
      <button onClick={fetchQuotes} disabled={quotesLoading}>
        Refresh Quotes
      </button>
    </div>
  );
}

RampFormState

FieldTypeDescription
stepRampStepCurrent step in the flow
flowType'buy' | 'sell'Current flow type
fiatCurrencystringSelected fiat currency
fiatAmountstringEntered fiat amount
cryptoCurrencystringSelected crypto currency
cryptoAmountstringCrypto amount
networkstringSelected blockchain network
paymentMethodIdstringSelected payment method
walletAddressstringEntered wallet address
selectedProviderstring | nullSelected gateway ID
selectedQuoteQuote | nullSelected quote
customerIdstringCustomer ID
emailstringCustomer email
errorMessagestring | nullCurrent error message

RampStep Values

StepDescription
amountCurrency and amount selection
quotesQuote comparison view
walletWallet address entry
checkoutProvider checkout (iframe/redirect)
processingWaiting for transaction completion
completeSuccess screen
errorError screen

Data Hooks

Standalone hooks for direct API access without the full form UI. Use these to build completely custom checkout experiences.

useRampConfig

Fetches supported gateways, currencies, and payment methods.
import { useRampConfig } from '@nowramp/form';

function CurrencyPicker() {
  const { config, loading, error, refetch } = useRampConfig(
    { apiUrl: 'https://api.nowramp.com', projectId: 'your_project_id' },
    'buy'
  );

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <select>
      {config?.fiats.map(fiat => (
        <option key={fiat.code} value={fiat.code}>
          {fiat.symbol} {fiat.name}
        </option>
      ))}
    </select>
  );
}
Returns:
FieldTypeDescription
configOnrampSupported | nullSupported configuration
loadingbooleanLoading state
errorError | nullError if failed
refetch() => Promise<void>Manually refetch

useQuotes

Fetches and ranks quotes from all enabled gateways. Auto-refreshes when params change.
import { useQuotes } from '@nowramp/form';

function QuoteList() {
  const { quotes, loading, error } = useQuotes(
    { apiUrl: 'https://api.nowramp.com', projectId: 'your_project_id' },
    {
      fiatCurrency: 'USD',
      fiatAmount: '100',
      cryptoCurrency: 'ETH',
      network: 'ethereum'
    }
  );

  if (loading) return <div>Fetching quotes...</div>;

  return (
    <div>
      {quotes?.quotes.map(q => (
        <div key={q.gatewayId}>
          {q.gatewayName}: {q.cryptoAmount} {q.cryptoCurrency}
          {q.isBestRate && <span> (Best Rate)</span>}
        </div>
      ))}
    </div>
  );
}
Pass null as the second argument to skip fetching (useful when form inputs are incomplete). Returns:
FieldTypeDescription
quotesQuotesResponse | nullRanked quotes
loadingbooleanLoading state
errorError | nullError if failed
refetch() => Promise<void>Manually refetch

useCheckoutIntent

Creates a checkout order with a selected gateway.
import { useCheckoutIntent } from '@nowramp/form';

function CheckoutButton() {
  const { order, loading, error, createOrder, reset } = useCheckoutIntent(
    { apiUrl: 'https://api.nowramp.com', projectId: 'your_project_id' }
  );

  const handleCheckout = async () => {
    const intent = await createOrder({
      gateway: 'gateway_a',
      fiatCurrency: 'USD',
      fiatAmount: '100',
      cryptoCurrency: 'ETH',
      network: 'ethereum',
      walletAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f1bD21'
    });

    if (intent.checkout.method === 'iframe') {
      setIframeUrl(intent.checkout.url);
    } else {
      window.location.href = intent.checkout.url;
    }
  };

  return <button onClick={handleCheckout} disabled={loading}>Checkout</button>;
}
Returns:
FieldTypeDescription
orderCheckoutIntent | nullCreated checkout intent
loadingbooleanLoading state
errorError | nullError if failed
createOrder(params) => Promise<CheckoutIntent>Create checkout
reset() => voidReset state

useTransaction

Polls transaction status until it reaches a terminal state.
import { useTransaction } from '@nowramp/form';

function OrderTracker({ orderId }: { orderId: string }) {
  const { status, loading } = useTransaction(
    { apiUrl: 'https://api.nowramp.com' },
    orderId,
    { pollInterval: 5000, initialDelay: 15000 }
  );

  if (!status) return <div>Loading...</div>;

  return (
    <div>
      <p>Status: {status.status}</p>
      {status.transactionHash && (
        <p>TX: {status.transactionHash}</p>
      )}
    </div>
  );
}
The initialDelay option is useful when embedding a provider checkout iframe — it gives the user time to complete payment before polling starts.
Returns:
FieldTypeDescription
statusTransaction | nullCurrent transaction status
loadingbooleanLoading state
errorError | nullError if failed
refetch() => Promise<void>Manually refetch

Theming

Light / Dark Mode

<RampForm projectId="..." theme="dark" />

Custom Colors

Override individual colors for precise brand matching:
<RampForm
  projectId="..."
  theme="dark"
  accentColor="#6366F1"
  bgColor="#1a1a2e"
  surfaceColor="#16213e"
  inputBgColor="#0f3460"
  textColor="#e0e0e0"
  textSecondaryColor="#a0a0a0"
  textMutedColor="#666666"
  successColor="#6366F1"
  borderColor="#222222"
  borderRadius="10px"
/>
Color mapping guide:
PropApplies to
accentColorButtons, links, active states, progress indicators
bgColorMain background of the form
surfaceColorCard and panel backgrounds
inputBgColorInput fields, pills, dropdowns
textColorPrimary text, headings
textSecondaryColorLabels, secondary text
textMutedColorHints, placeholders, disabled text
successColorSuccess indicators, rate display
borderColorBorders on cards, inputs, dividers
borderRadiusCorner rounding on all elements

Skin Presets

<RampForm projectId="..." skinId="midnight" />
Skins apply a coordinated set of colors and styles. Available skins are exported from the package as SKINS.

Standalone Mode (IIFE)

For non-React apps (plain HTML, PHP, WordPress, etc.), use the standalone IIFE build.
<script src="https://cdn.example.com/form/latest/nowramp-form.iife.js"></script>
<div id="nowramp"></div>
<script>
  NowRampForm.mount('#nowramp', {
    projectId: 'your_project_id',
    apiUrl: 'https://api.nowramp.com',
    assetBaseUrl: 'https://cdn.example.com/form/latest',
    theme: 'light',
    onComplete: function(tx) {
      console.log('Purchase complete:', tx.orderId);
    }
  });

  // To unmount later:
  // NowRampForm.unmount('#nowramp');
</script>
FunctionDescription
NowRampForm.mount(selector, props)Mount the form into a DOM element
NowRampForm.unmount(selector)Unmount a previously mounted form
The mount function accepts the same props as the RampForm component.

Next.js Integration

// app/buy/page.tsx
'use client';

import { RampForm } from '@nowramp/form';

export default function BuyPage() {
  return (
    <div className="max-w-md mx-auto py-8">
      <RampForm
        projectId={process.env.NEXT_PUBLIC_NOWRAMP_PROJECT_ID!}
        apiUrl={process.env.NEXT_PUBLIC_NOWRAMP_API_URL}
        theme="light"
        onComplete={(tx) => {
          window.location.href = `/orders/${tx.orderId}`;
        }}
      />
    </div>
  );
}
Always use the 'use client' directive in Next.js App Router since @nowramp/form uses React hooks and browser APIs.

Next Steps