React Component
Wrap the embed script in a React component for easy integration:import { useEffect, useRef } from "react";
declare global {
interface Window {
HypermidWidget: any;
}
}
interface HypermidWidgetProps {
partnerId?: string;
theme?: "dark" | "light";
mode?: "swap" | "gas" | "fund";
modes?: string;
defaultFromChain?: number;
defaultToChain?: number;
accentColor?: string;
bgPrimary?: string;
bgCard?: string;
fontFamily?: string;
borderRadius?: number;
buttonRadius?: number;
width?: string;
height?: string;
onReady?: () => void;
onSwapComplete?: (result: any) => void;
onError?: (error: any) => void;
}
export function HypermidWidget(props: HypermidWidgetProps) {
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const script = document.createElement("script");
script.src = "https://widget.hypermid.io/v1/embed.js";
script.onload = () => {
window.HypermidWidget.init({
containerId: "hypermid-react-widget",
partnerId: props.partnerId,
theme: props.theme || "dark",
mode: props.mode || "swap",
modes: props.modes,
defaultFromChain: props.defaultFromChain,
defaultToChain: props.defaultToChain,
accentColor: props.accentColor,
bgPrimary: props.bgPrimary,
bgCard: props.bgCard,
fontFamily: props.fontFamily,
borderRadius: props.borderRadius,
buttonRadius: props.buttonRadius,
width: props.width || "420px",
height: props.height || "700px",
onReady: props.onReady,
onExecute: props.onSwapComplete,
onError: props.onError,
});
};
document.body.appendChild(script);
return () => {
window.HypermidWidget?.destroy();
document.body.removeChild(script);
};
}, []);
return <div id="hypermid-react-widget" ref={containerRef} />;
}
Usage
<HypermidWidget
partnerId="your-partner-id"
theme="dark"
mode="swap"
defaultFromChain={1}
defaultToChain={42161}
accentColor="#FF6B35"
fontFamily="Inter"
onSwapComplete={(result) => console.log("Done!", result)}
/>
Next.js
For Next.js, use the component with"use client" directive since it uses browser APIs:
"use client";
import { HypermidWidget } from "@/components/HypermidWidget";
export default function SwapPage() {
return (
<div className="flex justify-center items-center min-h-screen">
<HypermidWidget
partnerId="your-partner-id"
theme="dark"
defaultFromChain={1}
defaultToChain={42161}
onSwapComplete={(result) => {
// Update your app state
console.log("Swap completed:", result.txHash);
}}
/>
</div>
);
}
The embed script is loaded client-side only. No SSR issues — the widget mounts after hydration.
Remix / React Router
Works the same way in Remix or React Router:import { HypermidWidget } from "~/components/HypermidWidget";
export default function SwapRoute() {
return (
<div style={{ display: "flex", justifyContent: "center", padding: 40 }}>
<HypermidWidget
partnerId="your-partner-id"
theme="dark"
defaultFromChain={1}
defaultToChain={42161}
/>
</div>
);
}
Dynamic Updates
To update the widget after mount, keep a ref to the globalHypermidWidget:
import { useCallback } from "react";
function SwapPage() {
const switchToLight = useCallback(() => {
window.HypermidWidget?.update({ theme: "light" });
}, []);
const setChain = useCallback((chainId: number) => {
window.HypermidWidget?.setSwap({ fromChain: chainId });
}, []);
return (
<div>
<button onClick={switchToLight}>Light Mode</button>
<button onClick={() => setChain(42161)}>Arbitrum</button>
<HypermidWidget partnerId="your-partner-id" />
</div>
);
}