Skip to content

UI — Build an embeddable Stellar Explain widget for third-party websites #514

@Tinna23

Description

@Tinna23

Description

Build a lightweight, embeddable widget that any website — a wallet, an exchange, a Stellar app — can drop in with a single <script> tag to show a Stellar Explain result inline. This is one of the highest-leverage distribution features: every website that embeds the widget is a new discovery channel for Stellar Explain.

Widget API

Script tag embed (easiest integration)

<!-- Embed a specific transaction -->
<div id="stellar-explain-widget" data-hash="5a7fc615..."></div>
<script src="https://stellar-explain.xyz/widget.js" async></script>
<!-- Embed a specific account -->
<div id="stellar-explain-widget" data-address="GABC..."></div>
<script src="https://stellar-explain.xyz/widget.js" async></script>

Widget appearance

A compact card (400px wide, auto height) with:

  • Stellar Explain logo + "Powered by Stellar Explain" footer link
  • Transaction: status badge, hash (truncated), summary, key fields
  • Account: address (truncated), XLM balance, asset count, summary
  • A "View full explanation →" link to the full result page
  • Dark theme by default with a data-theme="light" override option

What To Build

packages/ui/public/widget.js

A self-contained vanilla JS file (no framework dependency) that:

  1. Finds all #stellar-explain-widget divs on the page
  2. Reads data-hash or data-address attribute
  3. Creates an <iframe> pointing to /widget/tx/:hash or /widget/account/:address
  4. Injects the iframe into the div with sensible defaults (no border, full width, min-height)

The widget uses an iframe to guarantee style isolation — the host page's CSS cannot affect it.

src/app/widget/tx/[hash]/page.tsx

A stripped-down version of the transaction result page:

  • No AppShell header, no navigation, no panels
  • Just the essential cards: status, summary, key timeline fields, payment summary
  • Dark background, compact layout
  • "View full explanation →" link at the bottom

src/app/widget/account/[address]/page.tsx

Same pattern for accounts:

  • Balance, asset count, signer count, summary
  • "View full explanation →" link

src/app/widget/layout.tsx

A minimal layout with no global navigation — just the page content.

next.config.ts update

Add CORS headers for widget routes so they can be loaded cross-origin:

async headers() {
  return [
    {
      source: '/widget/:path*',
      headers: [
        { key: 'X-Frame-Options', value: 'ALLOWALL' },
        { key: 'Content-Security-Policy', value: 'frame-ancestors *' },
      ],
    },
  ]
}

Key Files

New files:

  • packages/ui/public/widget.js
  • src/app/widget/tx/[hash]/page.tsx
  • src/app/widget/account/[address]/page.tsx
  • src/app/widget/layout.tsx

Modified files:

  • next.config.ts (add CORS headers for /widget routes)

Acceptance Criteria

  • Pasting the script tag on any HTML page renders the widget correctly
  • data-hash shows transaction explanation widget
  • data-address shows account explanation widget
  • Widget loads in an iframe with correct CORS headers
  • Host page CSS cannot bleed into the widget
  • "View full explanation →" link opens the full page in a new tab
  • Widget is responsive within its container (min 300px, max 600px)
  • Dark theme by default, data-theme="light" override works
  • Widget displays a graceful error state if hash/address is invalid
  • widget.js is under 10KB minified
  • TypeScript compiles with no errors
  • Tested on Chrome, Firefox, and Safari

Complexity: High · 200 pts

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official Campaignfrontendcreate high-quality web applications with the power of React components.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions