How to Embed a Crypto Swap Widget on Your Website (2026 Step-by-Step Guide)

How to Embed a Crypto Swap Widget on Your Website (Step-by-Step)
Quick Answer (TL;DR) To embed a crypto swap widget on your website: (1) Register as a partner at xgram.io to get your partner ID. (2) Copy the one-line iframe embed code. (3) Paste it into your website's HTML where you want the widget to appear. (4) Optionally configure currency pairs, colors, and theme via URL parameters. Total setup time: 15 minutes. The widget handles all exchange logic — you earn revenue share on every completed swap. |
Adding a crypto exchange widget to your website is one of the fastest ways to add real utility and a passive revenue stream to any crypto-adjacent platform. You don't need to build exchange infrastructure, manage liquidity, or handle user funds. The widget handles everything — you just embed a code snippet.
This guide walks through the complete process: getting your partner ID, choosing between iframe and JavaScript embed methods, platform-specific instructions for WordPress, React, Webflow, and others, configuring parameters, setting up revenue tracking, and troubleshooting common issues.
Before You Start: What You Need
• A website or application where you want to embed the widget (any platform works)
• Access to edit your site's HTML or template code
• A Xgram partner account — free to create, no approval wait time
• Your partner ID from the Xgram partner dashboard
💡 Tip: You do not need a crypto wallet, exchange license, or any technical backend setup. The widget runs entirely on the provider's infrastructure. Your only job is to place the embed code on your page. |
Step 1: Get Your Partner ID
1 | Register as a Xgram Partner |
Go to xgram.io and navigate to the For Business → API or Widget section. Register as a partner. The process takes under 2 minutes and requires no approval — your partner ID is issued immediately.
Your partner ID is a unique string that links completed swaps to your account for revenue tracking. It looks like this:
partner_id: xg_a1b2c3d4e5f6 |
⚠ Important: Your partner ID must be included in every embed code you use. Without it, swaps completed through your widget will not be attributed to your account and you will not receive revenue share earnings. |
Method 1: iframe Embed — Simplest Setup
The iframe method works on any website or platform that allows custom HTML. No JavaScript required. This is the recommended method for WordPress, Webflow, Squarespace, Ghost, and any CMS with a custom HTML component.
2 | Copy the iframe embed code |
<iframe src="https://xgram.io/widget?ref=YOUR_PARTNER_ID&from=BTC&to=ETH&theme=light" width="100%" height="520" frameborder="0" scrolling="no" allow="clipboard-write" style="border-radius: 12px; border: none; display: block;" ></iframe> |
3 | Customize the embed URL parameters |
Edit the src URL to configure the widget for your audience. Key parameters:
• ref=YOUR_PARTNER_ID — replace with your actual partner ID (required)
• from=BTC — default input currency (use ticker symbol)
• to=ETH — default output currency
• theme=light — use light or dark to match your site
💡 Tip: Pre-selecting a relevant currency pair for your page context dramatically improves conversion. A Bitcoin article should show from=BTC. A DeFi page might show from=ETH&to=USDC. Match the default pair to what your readers are thinking about. |
4 | Paste the code on your page |
Paste the iframe code into your page HTML wherever you want the widget to appear. For most CMS platforms, this means adding a 'Custom HTML' or 'Embed' block and pasting the code there. The widget will render at the location of the embed code.
💡 Tip: Place the widget above the fold on high-intent pages — coin pages, price trackers, portfolio views. Widgets placed in the main content area convert significantly better than sidebar or footer placements. |
Method 2: JavaScript Embed — Full Control
The JavaScript method gives you programmatic control over initialization, event handling, and dynamic configuration. This is the recommended method for React, Next.js, Vue, and any JavaScript-based application.
5 | Add the widget script to your page |
Add this script tag before the closing </body> tag. Use async to avoid blocking page load:
<script src="https://xgram.io/widget.js" async></script> |
6 | Add a container element |
<div id="xgram-widget"></div> |
7 | Initialize the widget with your configuration |
window.XgramWidget.init({ container: "#xgram-widget", partnerId: "YOUR_PARTNER_ID", // required defaultFrom: "BTC", defaultTo: "ETH", theme: "light", // "light" | "dark" | "auto" primaryColor: "#1A73E8", // your brand color borderRadius: "12px", width: "100%", height: "520px", lang: "en", // interface language fixedRate: false // default rate mode }); |
React / Next.js Implementation
In React, initialize the widget inside a useEffect hook to ensure it runs after the component mounts and the DOM is available:
import { useEffect } from 'react';
export default function CryptoWidget() { useEffect(() => { // Load widget script dynamically const script = document.createElement('script'); script.src = 'https://xgram.io/widget.js'; script.async = true; script.onload = () => { window.XgramWidget.init({ container: '#xgram-widget', partnerId: 'YOUR_PARTNER_ID', defaultFrom: 'BTC', defaultTo: 'ETH', theme: 'light', primaryColor: '#1A73E8', width: '100%', height: '520px', }); }; document.body.appendChild(script);
// Cleanup on unmount return () => { document.body.removeChild(script); }; }, []); // Empty array = run once on mount
return <div id="xgram-widget" />;; } |
⚠ Important: Always use an empty dependency array [] in useEffect. Without it, the widget will re-initialize on every render, causing duplicate instances and broken behavior. |
Vue.js Implementation
<template> <div ref="widgetContainer"></div> </template>
<script> export default { mounted() { const script = document.createElement('script'); script.src = 'https://xgram.io/widget.js'; script.async = true; script.onload = () => { window.XgramWidget.init({ container: this.$refs.widgetContainer, partnerId: 'YOUR_PARTNER_ID', defaultFrom: 'BTC', defaultTo: 'ETH', theme: 'light', width: '100%', height: '520px', }); }; document.body.appendChild(script); } }; </script> |
Full Parameter Reference
Complete list of configuration parameters for both iframe URL and JS initialization:
Parameter | Required? | Example value | Description |
ref | Required | YOUR_PARTNER_ID | Your partner ID for revenue tracking. Without this, swaps are not attributed to your account. |
from | Recommended | BTC, ETH, USDT… | Pre-selects the input currency. Use the ticker symbol. Improves UX for contextual embeds. |
to | Recommended | ETH, XMR, BNB… | Pre-selects the output currency. Combine with from= for a specific default pair. |
amount | Optional | 0.01, 100, 500 | Pre-fills the input amount field. Useful for checkout or payment scenarios. |
theme | Optional | light, dark, auto | Sets widget color theme. Auto follows system preference. |
primaryColor | Optional | #1A73E8 | Hex color for buttons and accents. Use your brand color. |
borderRadius | Optional | 12px, 0px, 20px | Corner rounding on the widget container. |
lang | Optional | en, es, de, pt, ru | Interface language. Defaults to browser language if not set. |
fixedRate | Optional | true, false | If true, defaults users to fixed rate mode on load. |
hideHeader | Optional | true, false | Hides the widget header bar for a more minimal embedded appearance. |
Platform-Specific Instructions
Platform | Method | How to Embed | Notes |
WordPress | iframe | Paste in Custom HTML block or Text widget. Works with Elementor, Divi, WPBakery. | No plugin needed — works with any theme |
Webflow | iframe | Add Embed component anywhere on canvas. Paste iframe code. | Style wrapper div to control sizing |
Squarespace | iframe | Add Code Block in page editor. Paste iframe code. Check 'Use embed code' toggle. | Some plans restrict custom code — check your plan |
Shopify | iframe | Paste in theme liquid template or use Custom HTML section. | Embed on product or collection pages for context |
React / Next.js | JS (recommended) | Use useEffect to initialize after mount. Add container div in JSX. | Lazy-load for performance — init on viewport entry |
Vue.js | JS (recommended) | Initialize in mounted() lifecycle hook. Use ref for container. | Use v-if to conditionally render only when needed |
Static HTML | Both | iframe is simplest. JS gives more control. Add before </body>. | Fastest setup of any platform |
Ghost / Substack | iframe | Paste in HTML card. Some platforms restrict iframes — test first. | Check platform iframe policy before embedding |
Verifying Revenue Tracking
After embedding the widget, verify that revenue tracking is working correctly before promoting the integration:
1. Open your website and inspect the widget's iframe src URL in browser DevTools — confirm ref=YOUR_PARTNER_ID is present in the URL.
2. Complete a small test swap through your embedded widget (use the minimum amount for the pair you selected).
3. Wait 10–15 minutes, then check your Xgram partner dashboard. The test swap should appear under attributed transactions.
4. If the swap does not appear, double-check that the partner ID in your embed code exactly matches the ID shown in your dashboard — they are case-sensitive.
💡 Tip: Do this verification step before driving traffic to your embedded widget. A missing or incorrect partner ID means lost earnings on every swap — there is no retroactive attribution for historical transactions. |
Placement and Conversion Tips
Where to Place the Widget
• Above the fold on coin or asset pages — highest intent, best conversion
• In-line within articles that mention specific coins — contextual match increases engagement
• On a dedicated 'Exchange' or 'Swap' page — users who navigate there have the highest intent
• At checkout on crypto payment flows — conversion point where swap is immediately actionable
Sizing for Different Contexts
• Full-width embed (width='100%', height='520px') — use as the main content element on a dedicated swap page
• Column embed (width='400px', height='520px') — works alongside editorial content in a two-column layout
• Mobile-first (width='100%', height='480px') — reduce height slightly on mobile to avoid excessive scrolling
White-Label for Branded Platforms
• Set primaryColor to your brand's hex color — buttons and accents will match your design system
• Use theme='dark' if your site has a dark background — avoids the jarring contrast of a white widget on a dark page
• Set hideHeader=true for the most minimal, native-feeling embed
• Full logo replacement is available for high-volume partners — contact the partner team
Troubleshooting: Common Problems and Fixes
Problem | Cause | Fix |
Widget blank / not showing | iframe blocked by CSP or browser security | Add widget domain to Content-Security-Policy: frame-src directive in your server headers |
'Refused to display in frame' | X-Frame-Options header blocking embed | This is the provider's header setting — contact support if Xgram widget shows this error |
Rates not loading | Missing or invalid partner ID (ref= param) | Check that ref=YOUR_PARTNER_ID is in the embed URL and matches your dashboard ID exactly |
Widget cut off on mobile | Fixed pixel width/height on iframe | Replace fixed widths with width='100%' and set min-height instead of height |
Revenue not being tracked | Partner ID absent from embed code | Verify ref= parameter is present. Check partner dashboard for recent swap attributions. |
Wrong default currency showing | from= / to= params not set or misspelled | Use exact ticker symbols (BTC not bitcoin, USDT not tether). Check symbol list in docs. |
Widget loads slowly | Script loaded synchronously in <head> | Move <script> tag to before </body>, or add async / defer attribute |
Widget fails after React re-render | JS widget re-initializes on each render | Initialize widget once in useEffect with empty dependency array [] |
CORS errors in console | API calls blocked by browser CORS policy | This is a configuration issue — contact Xgram partner support with the error details |
Frequently Asked Questions
How long does it take to embed a crypto swap widget?
Using the iframe method, embedding the Xgram Widget takes approximately 15 minutes from registration to a live widget on your page. This includes creating a partner account (2 min), copying and customizing the embed code (5 min), pasting it into your CMS (5 min), and verifying revenue tracking with a test swap (3 min). The JavaScript method takes slightly longer — 30–45 minutes — due to the initialization code setup.
Do I need to know how to code to embed a crypto widget?
For the iframe method, no coding knowledge is required. You paste a single HTML snippet into your website's custom HTML block — this works in WordPress, Webflow, Squarespace, and most other website builders without writing any code. For the JavaScript method, basic HTML and JS familiarity is helpful, and for React or Vue integration, you should be comfortable working in a component-based JavaScript framework.
Will the widget work on mobile devices?
Yes. The Xgram Widget is fully responsive. Use width='100%' in your embed code to ensure the widget adapts to the screen width. Avoid fixed pixel widths (e.g., width='400px') on mobile layouts — they cause horizontal scrolling on small screens. A height of 480–520px works well for most mobile contexts.
How does revenue tracking work?
Revenue tracking works through your partner ID, passed as the ref= parameter in the widget embed URL or the partnerId field in JavaScript initialization. Every swap completed through a widget with your partner ID is attributed to your account. Earnings (your share of the exchange fee) accumulate automatically and are visible in your partner dashboard. There is no manual reporting or minimum volume required.
Can I embed the widget on multiple websites?
Yes. You can use the same partner ID across multiple websites — all attributions flow into the same partner account. If you want to track performance separately by site, contact the Xgram partner team to set up sub-IDs or separate partner accounts for each property.
Can I restrict the widget to specific currency pairs?
Yes. You can pre-configure the default pair using from= and to= URL parameters. To lock the widget to a single pair (preventing users from changing currencies), use the lockedPair=true parameter — this is available in JavaScript initialization mode and is useful for payment-specific embeds where only one swap direction is relevant.
What happens if a user's swap fails?
The Xgram Widget handles failed transactions automatically. If a swap cannot be completed (network congestion, minimum amount not met, etc.), the widget displays an error message and prompts the user to retry. No funds are lost — if a deposit is received but the swap cannot execute, Xgram's support team initiates a refund to the sender's address. Your platform does not need to handle any of this logic.
Does embedding the widget affect my website's performance?
The widget loads asynchronously and has a minimal footprint. Using the async attribute on the script tag ensures it does not block page rendering. For best performance, initialize the widget only when it enters the user's viewport (lazy initialization) rather than on page load — this is especially important for pages where the widget appears below the fold.
Private crypto swaps
Best rates. Secure. Wallet to wallet
