Render the full campaign detail experience (hero, tasks, rewards, requirements, claim flow) for a single campaign — embedded as an iframe that you can drop inside your own modal, drawer, or full-page layout.
This widget is designed for partners who maintain their own campaign listing UI but want to delegate the campaign detail / claim flow to Legion.
npm install @legionhandtech/lht-react-widgetsReact 17+ is a peer dependency.
1import { LegionCampaignDetail } from "@legionhandtech/lht-react-widgets";
2
3function App() {
4 return (
5 <LegionCampaignDetail
6 baseUrl="https://your-legion-domain.com"
7 id="00000000-0000-0000-0000-000000000001"
8 theme="light"
9 />
10 );
11}You can also import from the dedicated sub-path:
import { LegionCampaignDetail } from "@legionhandtech/lht-react-widgets/campaign-detail";The canonical PMCAV pattern — keep your campaign listing UI, open your own modal, embed the widget inside it:
1import { useState } from "react";
2import { Modal } from "@mantine/core";
3import { LegionCampaignDetail } from "@legionhandtech/lht-react-widgets";
4
5function CampaignList({ campaigns, token }) {
6 const [activeId, setActiveId] = useState<string | null>(null);
7
8 return (
9 <>
10 {campaigns.map((c) => (
11 <button key={c.id} onClick={() => setActiveId(c.id)}>
12 {c.title} — View details
13 </button>
14 ))}
15
16 <Modal opened={!!activeId} onClose={() => setActiveId(null)} size="lg">
17 {activeId && (
18 <LegionCampaignDetail
19 id={activeId}
20 apiKey={token}
21 baseUrl="https://your-legion-domain.com"
22 onClose={() => setActiveId(null)}
23 onClaim={({ id }) => {
24 console.log("Claimed campaign", id);
25 setActiveId(null);
26 }}
27 />
28 )}
29 </Modal>
30 </>
31 );
32}| Prop | Type | Default | Description |
|---|---|---|---|
id | string | required | Campaign UUID |
baseUrl | string | required | Base URL of your Legion deployment |
apiKey | string | — | Bearer token / API key for authenticated mode |
theme | "light" | "dark" | "light" | Theme preset |
width | string | "100%" | Container width (CSS value) |
height | string | number | "auto" | Container height (CSS value or px number) |
className | string | — | CSS class applied to the outer container |
style | React.CSSProperties | — | Inline styles merged into the container |
onLoad | (detail) => void | — | Called when the widget iframe finishes loading |
onError | (message: string) => void | — | Called if the widget iframe fails to load |
onClose | () => void | — | Called when the embedded view requests dismissal (use this to close your modal) |
onClaim | ({ id }) => void | — | Called after a successful claim / begin event |
All theming props are optional and forwarded to the iframe as kebab-case query parameters. See the TypeScript CampaignDetailThemingProps interface for the complete list.
| Prop | Query Param | Example |
|---|---|---|
detailBackgroundColor | detail-background-color | "#ffffff" |
detailTextColor | detail-text-color | "#1a1b1e" |
detailPrimaryColor | detail-primary-color | "#228be6" |
detailBorderRadius | detail-border-radius | "12px" |
detailShadow | detail-shadow | "0 2px 8px rgba(0,0,0,0.08)" |
detailTitleSize | detail-title-size | "1.5rem" |
detailFontFamily | detail-font-family | "Inter, system-ui, sans-serif" |
1import { useRef } from "react";
2import {
3 LegionCampaignDetail,
4 LegionCampaignDetailHandle,
5} from "@legionhandtech/lht-react-widgets";
6
7function App() {
8 const widgetRef = useRef<LegionCampaignDetailHandle>(null);
9
10 return (
11 <>
12 <button onClick={() => widgetRef.current?.refresh()}>Reload</button>
13 <LegionCampaignDetail
14 ref={widgetRef}
15 baseUrl="https://your-legion-domain.com"
16 id="…uuid…"
17 />
18 </>
19 );
20}| Method | Description |
|---|---|
refresh() | Reloads the widget iframe (e.g. after the host context changes) |
import "@legionhandtech/lht-react-widgets/campaign-detail-web-component";1<legion-campaign-detail
2 id="00000000-0000-0000-0000-000000000001"
3 base-url="https://your-legion-domain.com"
4 auth-token="…"
5 theme="light"
6>
7</legion-campaign-detail>The element dispatches close and claim CustomEvents that mirror the React component's onClose / onClaim callbacks.
1import type {
2 CampaignDetailWidgetProps,
3 CampaignDetailThemingProps,
4 LegionCampaignDetailHandle,
5} from "@legionhandtech/lht-react-widgets";