Skip to main content
Prewarming loads the MoonPay widget in a hidden iframe or web view before your customer asks for it. The widget downloads its code, loads your account’s theme and configuration, and renders its first screen in the background. When the customer taps your buy or sell button, you make the already-loaded widget visible. On a cold load the widget can take several seconds to become usable, especially on mobile networks. Prewarming moves that time to a moment when the customer is not waiting.
Prewarming is supported on the /v2/buy and /v2/sell widget URLs only. See Widget URLs.

When to prewarm

Prewarm when there is a strong signal that the customer is about to open the widget. For example:
  • The customer opens a screen that has your buy or sell button.
  • The customer selects a token they do not hold enough of.
Do not prewarm on every page load or app launch. Each prewarm loads the full widget, which uses the customer’s data and memory.

How it works

  1. Build the widget URL with all the parameters you need, including the signature if you use one.
  2. Create the iframe or web view with that URL. Keep it hidden but at its final size.
  3. Listen for the MOONPAY_READY message.
  4. When the customer taps your button and MOONPAY_READY has arrived, make the widget visible.
If the customer taps before MOONPAY_READY arrives, show your own loading state and reveal the widget when the message arrives. The widget keeps loading from wherever the background load reached. Always add a fallback. If MOONPAY_READY has not arrived 5 seconds after the customer taps your button, reveal the widget anyway. The widget then shows its own loading screen or any error, instead of leaving the customer on your loading state.

Widget URLs

Add your on-ramp or off-ramp parameters as a query string, for example https://buy.moonpay.com/v2/buy?apiKey=pk_live_123&currencyCode=eth. To test in sandbox, use your pk_test_ API key with the same URLs. The widget switches to the sandbox environment based on the key.

The ready message

When the widget has rendered its first screen, it sends this message to the page or app that hosts it:
Your listener must ignore repeat MOONPAY_READY messages from the same load.

Prewarm in a web page

Keep the iframe in the page at its final size, fully transparent, and unable to receive clicks or focus. Do not use display: none. A widget that has no size cannot lay out its first screen correctly.
Your domain must be allowed to embed the widget in an iframe. This is the same requirement as a standard iframe integration.

Prewarm in a React Native app

Use the WebView component from react-native-webview. It renders a WKWebView on iOS and an Android WebView on Android, and it can load the widget while it is hidden. In-app browsers, such as expo-web-browser, SFSafariViewController, and Chrome Custom Tabs, cannot be used to prewarm. They are presented by the operating system, and they start to load only when they open. Render the WebView at its final size behind your content. Bring it forward when the customer has tapped your button and the widget is ready.
If you use SFSafariViewController or Chrome Custom Tabs today for Apple Pay or Google Pay support, switching to a web view to prewarm can make those payment methods unavailable. See Mobile payments.

Best practices

  • Use the final URL. Build the URL with the amount, currency, wallet address, and signature before you prewarm. If a parameter changes, you must load a new URL, and the customer waits for a full load again.
  • Use one prewarmed widget at a time. Remove any earlier hidden widget before you create a new one.
  • Do not reuse a closed widget. After the customer closes the widget or completes a transaction, remove it. Prewarm a new one if the customer is likely to return.
  • Keep the hidden widget at its final size. The widget lays out its first screen for the size it has when it loads.
  • Keep it out of reach while hidden. Make sure the hidden widget cannot receive taps, clicks, keyboard focus, or screen reader focus.