Embeddable yield widgets for third-party distribution.
| Variant | URL |
|---|---|
| Standard (default) | /embed/vitalik.eth |
| Compact | /embed/vitalik.eth?variant=compact |
| Advanced | /embed/vitalik.eth?variant=advanced |
| Theme | ?theme=light · ?theme=dark · ?theme=auto (default) |
<iframe
src="https://yield.dexkit.com/embed/vitalik.eth?variant=standard&theme=auto"
title="Wallet yield estimate"
style="width:100%;max-width:420px;border:0;"
loading="lazy"
allowtransparency="true"
></iframe>Embed pages post height to the parent frame:
window.addEventListener("message", (event) => {
if (event.data?.type === "dexkit-yield:resize") {
iframe.style.height = `${event.data.height}px`;
}
});Message type: dexkit-yield:resize · payload: { height: number }.
| Variant | Content |
|---|---|
| compact | Monthly yield only |
| standard | Daily · monthly · yearly |
| advanced | Protocol breakdown (value + monthly yield per protocol) |
- No site header, footer, or navigation
- No analytics (
Umamiexcluded from embed layout) - Small “Powered by DexKit” footer link
robots: noindexon/embed/*(canonical pages remain at/[identifier])- CSP
frame-ancestors *on embed routes (next.config.ts)
src/components/widgets/
embed-runtime.tsx # Theme sync + ResizeObserver → postMessage
widget-footer.tsx # “Powered by DexKit”
yield-widgets.tsx # Compact / Standard / Advanced UI
yield-widget.tsx # Variant switch
JSON yield snapshot for widgets and integrations.
Example: GET /api/yield/vitalik.eth
Response: WalletYieldApiResponse — see src/lib/api/serialize-yield.ts
| Field | Description |
|---|---|
summary |
dailyUsd, monthlyUsd, yearlyUsd |
chains |
Per-chain protocol groups and positions |
calculatedAt |
ISO timestamp |
Headers:
Access-Control-Allow-Origin: *(CORS for cross-origin widgets)Cache-Control: public, s-maxage=300
Errors: 404 when wallet cannot be resolved.
OPTIONS supported for CORS preflight.
Not implemented. Architecture below for future work.
<script
src="https://yield.dexkit.com/widget.js"
async
></script>
<dexkit-yield
address="vitalik.eth"
variant="standard"
theme="auto"
></dexkit-yield>- Define custom element
<dexkit-yield>(shadow DOM optional for style isolation). - Fetch
GET /api/yield/{address}— no third-party trackers in the loader. - Render variant UI (reuse React via islands, or lightweight vanilla templates).
- Resize —
ResizeObserveron host element; no iframe required. - Theming —
themeattribute →light|dark|auto. - Error states — wallet not found, rate limited, network error.
public/
widget.js # Bundled IIFE (~15–25 KB gzipped target)
src/widgets/ # Source (build into public/widget.js)
custom-element.ts
render-compact.ts
render-standard.ts
render-advanced.ts
api-client.ts
theme.ts
# Future script
esbuild src/widgets/entry.ts --bundle --minify --outfile=public/widget.js --format=iifeVersioned URL option: /widget/v1.js for cache busting without breaking embeds.
| Attribute | Values | Default |
|---|---|---|
address |
ENS or 0x… |
required |
variant |
compact | standard | advanced |
standard |
theme |
light | dark | auto |
auto |
currency |
USD (future) |
USD |
- API remains read-only GET
- No cookies or localStorage in widget loader
- Sanitize
addressattribute before API call - CSP on host page is host’s responsibility; script only calls
yield.dexkit.comAPI
| iframe (Phase 1) | widget.js (Phase 2) | |
|---|---|---|
| Integration | Copy/paste iframe | One script + tag |
| Style isolation | Full | Shadow DOM or BEM classes |
| SEO | noindex embed | N/A (client-rendered) |
| Resize | postMessage | Native DOM height |
| CSP on parent | frame-src |
script-src |
Phase 1 iframes remain supported indefinitely for strict CSP environments that block third-party scripts.
Before wide distribution:
- Per-IP limits on
/api/yield/* - Optional API keys for high-volume partners
- CDN edge caching (already
s-maxage=300)
-
/embed/vitalik.ethrenders without header/footer -
?variant=compact|standard|advancedswitches layout -
?theme=light|darkoverrides system preference - No Umami script on embed pages
-
GET /api/yield/vitalik.ethreturns JSON with CORS headers - iframe
postMessageupdates parent height - Embed page allowed in cross-origin iframe (CSP
frame-ancestors *)