Workflows

How do I embed a fund factsheet or chart in a React app?

npm install @fundfactsapi/widgets gives you zero-dependency React components (GrowthChart, Donut, WeightBars, KeyFacts, RiskScale, ReturnsTable, FundFactsheet) that render the API payload. Server-side fetch, client render, or an iframe embed.Updated 12 September 2026 · by FundFacts API

Short answer

Fetch the payload server-side (a route handler or server component, so the key stays private) and pass data to the components from @fundfactsapi/widgets: FundFactsheet for the whole one-pager, or GrowthChart, Donut, WeightBars, KeyFacts, RiskScale, ProfileChips and the returns tables individually. They have no dependencies and are styled with CSS variables you can override. For a no-code embed, POST /factsheets with deliver: "link" returns an iframe URL.

Install and render

bash
npm install @fundfactsapi/widgets @fundfactsapi/sdk
tsx
// app/funds/[isin]/page.tsx (Next.js server component: the key never reaches the browser)
import { FundFacts } from "@fundfactsapi/sdk";
import { FundFactsheet } from "@fundfactsapi/widgets";
const ff = new FundFacts({ apiKey: process.env.FUNDFACTS_API_KEY! });
export default async function Page({ params }: { params: Promise<{ isin: string }> }) {
const { isin } = await params;
const fund = await ff.getFund(isin);
return <FundFactsheet fund={fund} accent="#1F5EFF" />;
}

Piece by piece

tsx
import { GrowthChart, Donut, WeightBars, KeyFacts, RiskScale, CalendarReturns } from "@fundfactsapi/widgets";
<KeyFacts data={fund.data} />
<RiskScale value={fund.data.riskRating} />
<GrowthChart points={fund.data.indexedPerformance.points} hasIndex={fund.data.indexedPerformance.hasIndex} />
<Donut items={fund.data.sector} title="Sectors" />
<WeightBars items={fund.data.topHoldings.map((h) => ({ label: h.name, weight: h.weight }))} title="Top holdings" />
<CalendarReturns data={fund.data.calendarReturns} />

Every component takes the payload's own shapes, so there is no mapping layer. Colours, fonts and radii are CSS variables (--ff-accent, --ff-fg, --ff-muted…) you set on a wrapper.

Iframe embed

bash
curl -s -X POST https://fundfactsapi.com/api/v1/factsheets -H "Authorization: Bearer $FUNDFACTS_API_KEY" -H "Content-Type: application/json" \
-d '{"isin":"IE00B4L5Y983","format":"html","deliver":"link"}' | jq .urls.embed
html
<iframe src="https://fundfactsapi.com/f/…?embed=1" width="100%" height="1200" loading="lazy" title="iShares Core MSCI World UCITS ETF factsheet"></iframe>

Keep the key on the server

Fetch in a server component, a route handler or an edge function, cache the payload until expiresAt, and send only fund to the client. The ETF comparison website use case shows the full page structure with caching and disclaimers.

Verify it yourself

The demo endpoint returns the live payload for a fund that is already in the store, without a key. Everything on this page can be checked against it.
bash
curl -s https://fundfactsapi.com/api/v1/demo/funds/IE00B4L5Y983 | jq '{name, asOf: .data.dataAsOf, ter: .data.headlineMetrics.ter, risk: .data.riskRating, top: .data.topHoldings[:3]}'

Frequently asked questions

Does the widget package need the SDK?

No; it renders any object with the API's shape. The SDK is only the convenient way to fetch it with types.

Try it on your own ISINs

One request returns key facts, holdings, risk and performance as JSON. Free plan, no card.