Guide
Web framework examples · Solana / USDC
React, Next.js, Vue, and Vanilla patterns for embedding the MoneyGram Ramps widget after the core Web guide. Pick a tab for your stack.
Tabs by frameworkWeb · SolanaUSDC
MoneyGram Ramps: Web framework examples (Solana / USDC)
Companion to the Web · Solana guide.
Runnable reference for the full Solana widget flow: Solana hub · clone and run on devnet. The tabbed snippets below are minimal embed patterns for an existing app.
React
TSX
import { useEffect, useRef, useState } from 'react' // Type definitions (add to your project)interface OnChainTransaction { chain: string to: string amount: string asset: string memo?: string rawTransaction: unknown} interface RampsSDK { open(): void close(): void destroy(): void} // SDK loaded via <script> tag in index.htmldeclare const RampsSDK: { createRamps: (config: any) => RampsSDK} const { createRamps } = RampsSDK function CashOutButton() { const containerRef = useRef<HTMLDivElement>(null) const rampsRef = useRef<RampsSDK | null>(null) const [isOpen, setIsOpen] = useState(false) async function handleOpenWidget() { if (!containerRef.current) return // Check if user is authenticated in your wallet if (!yourWallet.isConnected()) { alert('Please sign in to your wallet first') return } // Fetch session const session = await fetch('/api/moneygram-session', { method: 'POST' }) .then(res => res.json()) // Create widget const ramps = createRamps({ container: containerRef.current, sessionToken: session.sessionToken, widgetUrl: session.widgetUrl, wallet: { address: yourWallet.getPublicKey(), chain: 'solana', asset: 'USDC', walletType: 'non-custodial' }, onSignTransaction: async (tx: OnChainTransaction) => { return await signAndSendUsdc(tx) }, onComplete: (transaction) => { alert(`Cash pickup code: ${transaction.referenceNumber}`) setIsOpen(false) }, onClose: () => { setIsOpen(false) } }) rampsRef.current = ramps ramps.open() setIsOpen(true) } // Cleanup on unmount useEffect(() => { return () => { rampsRef.current?.destroy() } }, []) return ( <button onClick={handleOpenWidget} disabled={isOpen}> Cash Out USDC </button> {/* Container for widget iframe */} </div> )}
Next.js (App Router)
TSX
'use client' // Client component required for browser APIs import { useEffect, useRef } from 'react'import dynamic from 'next/dynamic' // Lazy load to avoid SSR issuesconst RampsWidget = dynamic( () => import('@/components/RampsWidget'), { ssr: false, loading: () => <div>Loading widget...</div> }) export default function CashOutPage() { return ( <h1>Cash Out USDC</h1> <RampsWidget /> </div> )}
components/RampsWidget.tsx:
TSX
'use client' import { useEffect, useRef } from 'react' // SDK loaded via <script> tagdeclare const RampsSDK: { createRamps: (config: any) => any }const { createRamps } = RampsSDK export default function RampsWidget() { const containerRef = useRef<HTMLDivElement>(null) const rampsRef = useRef<any>(null) useEffect(() => { async function initWidget() { if (!containerRef.current) return const session = await fetch('/api/moneygram-session', { method: 'POST' }) .then(res => res.json()) const ramps = createRamps({ container: containerRef.current, sessionToken: session.sessionToken, widgetUrl: session.widgetUrl, wallet: { address: yourWallet.getPublicKey(), chain: 'solana', asset: 'USDC', walletType: 'non-custodial' }, onSignTransaction: async (tx) => { // Sign and send USDC (implementation from the core Web guide, Step 4) const signature = await signAndSendUsdc(tx) return signature } }) rampsRef.current = ramps ramps.open() } initWidget() return () => { rampsRef.current?.destroy() } }, []) return <div ref={containerRef} />}
Vue 3
Vue
<template> <button @click="openWidget" :disabled="isOpen"> Cash Out USDC </button> </div></template> <script setup lang="ts">import { ref, onUnmounted } from 'vue' // Type definitionsinterface OnChainTransaction { chain: string to: string amount: string asset: string} // SDK loaded via <script> tag in index.htmldeclare const RampsSDK: { createRamps: (config: any) => any }const { createRamps } = RampsSDK const container = ref<HTMLDivElement | null>(null)const isOpen = ref(false)let ramps: any = null async function openWidget() { if (!container.value) return // Check if user is authenticated in your wallet if (!yourWallet.isConnected()) { alert('Please sign in to your wallet first') return } const session = await fetch('/api/moneygram-session', { method: 'POST' }) .then(res => res.json()) ramps = createRamps({ container: container.value, sessionToken: session.sessionToken, widgetUrl: session.widgetUrl, wallet: { address: yourWallet.getPublicKey(), chain: 'solana', asset: 'USDC', walletType: 'non-custodial' }, onSignTransaction: async (tx: OnChainTransaction) => { return await signAndSendUsdc(tx) }, onComplete: (transaction) => { alert(`Reference: ${transaction.referenceNumber}`) isOpen.value = false }, onClose: () => { isOpen.value = false } }) ramps.open() isOpen.value = true} onUnmounted(() => { ramps?.destroy()})</script> .widget-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 9999;}</style>
Vanilla JavaScript (no framework)
HTML
<!DOCTYPE html><html><head> <title>MoneyGram Cash Out</title> <script src="https://playground.xramps.moneygram.com/sdk/index.global.js"></script></head><body> <button id="cash-out-btn">Cash Out USDC</button> <div id="ramps-widget"></div> <script> const { createRamps } = window.RampsSDK document.getElementById('cash-out-btn').addEventListener('click', async () => { // Check if user is authenticated in your wallet if (!yourWallet.isConnected()) { alert('Please sign in to your wallet') return } // Fetch session const session = await fetch('/api/moneygram-session', { method: 'POST' }) .then(res => res.json()) // Create widget const ramps = createRamps({ container: document.getElementById('ramps-widget'), sessionToken: session.sessionToken, widgetUrl: session.widgetUrl, wallet: { address: yourWallet.getPublicKey(), chain: 'solana', asset: 'USDC', walletType: 'non-custodial' }, onSignTransaction: async (tx) => { // Sign and send USDC const signature = await signAndSendUsdc(tx) return signature }, onComplete: (transaction) => { alert('Cash pickup code: ' + transaction.referenceNumber) } }) ramps.open() }) async function signAndSendUsdc(tx) { // Implementation from Step 4 // ... return signature } </script></body></html>