Use this page as the complete guide for embedding and integrating the Price Alerts Widget. It includes a live demo, step-by-step instructions, API details, and troubleshooting tips.
The widget below is rendered by the exact script you will embed.
PriceAlertsWidget.render(target) API.Preferred usage (replace https://your-domain.example with the host of this service if embedding elsewhere):
<!-- Include the widget script -->
<script src="https://your-domain.example/static/widget.js" async></script>
<!-- Use the custom element anywhere on the page -->
<price-alerts-widget lang="auto" symbol="BTC" currency="usd"></price-alerts-widget>
Legacy wrapper (still supported):
<script src="/static/widget.js"></script>
<div id="pa-root"></div>
<script>window.PriceAlertsWidget.render('pa-root', { lang: 'auto', symbol: 'BTC' })</script>
If this page is served from the same host that will serve the widget, you can reference the relative path:
<script src="/static/widget.js"></script>
<price-alerts-widget lang="auto" currency="eur"></price-alerts-widget>
The widget can be used as a Custom Element or via a legacy wrapper.
<price-alerts-widget> supports attributes:
lang: Preferred language or locale (e.g. "nl", "en"), or "auto" to infer from the URL or <html lang>. Defaults to English.symbol: Optional default coin symbol to preselect (e.g. "ETH"). If omitted, the widget defaults to the first item or BTC.currency: Initial currency. One of "usd" or "eur". Defaults to eur.The global object window.PriceAlertsWidget exposes:
render(target, options?): Renders the widget into the specified target. target can be a string (element id) or a DOM element. options is an optional object with lang, symbol, and currency ("usd"|"eur", defaults to eur).Return value: void.
pa-widget__* convention.You can theme the widget by setting CSS variables on the element. Defaults are shown below.
price-alerts-widget {
--pa-font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
--pa-bg: #fff;
--pa-fg: #111827;
--pa-border-color: #e2e8f0;
--pa-border-width: 1px;
--pa-radius: 8px;
--pa-padding: 12px;
--pa-shadow: none;
--pa-accent: #2563eb;
--pa-accent-weak: #2563eb22;
--pa-muted: #6b7280;
--pa-input-height: 40px;
--pa-max-width: 480px;
--pa-min-height: 352px;
--pa-button-bg: #111827;
--pa-button-fg: #fff;
--pa-button-bg-hover: #0b1220;
}
Additionally, the outer container is exposed as a CSS part:
price-alerts-widget::part(container) {
box-shadow: 0 0 15px rgba(0,0,0,.2);
}
The widget calls the following endpoints on the same origin that serves /static/widget.js:
/api/v1/coins?currency=usd|eur — top coins with current price and image URL./api/v1/coin/<symbol>?currency=usd|eur — a single coin by symbol (first/best match). Response shape matches search results./api/v1/search?q=<query>¤cy=usd|eur — search by symbol or name; includes image URL./api/v1/alerts — submit a price alert./images/{symbol}.png — cached icon proxy./api/v1/coins (USD):
[
{ "id": "bitcoin", "symbol": "btc", "name": "Bitcoin", "price": 64000.12, "image": "https://<host>/images/btc.png" },
{ "id": "ethereum", "symbol": "eth", "name": "Ethereum", "price": 3200.45, "image": "https://<host>/images/eth.png" }
]
/api/v1/search?q=bit¤cy=eur:
/api/v1/coin/eth?currency=usd:
{
"id": "ethereum",
"symbol": "eth",
"name": "Ethereum",
"price": 3200.45,
"image": "https://<host>/images/eth.png"
}
[
{ "id": "bitcoin", "symbol": "btc", "name": "Bitcoin", "price": 59000.33, "image": "https://<host>/images/btc.png" }
]
POST /api/v1/alerts request body:
{
"email": "you@example.com",
"symbol": "BTC",
"currency": "usd",
"target": 65000,
"above": true
}
Success response:
{ "ok": true, "id": "abc123", "validated": false }
After submitting an alert, a confirmation email with a validation link is sent (if SMTP is configured). The link targets /validate/{token} and must be visited to activate the alert.
Access-Control-Allow-Origin: * and fetches data from the same origin that served it./images/{symbol}.png and cached for one hour.FIRESTORE_PROJECT_ID (and optional FIRESTORE_DATABASE_ID).SMTP_* env vars; otherwise they are skipped.render.