An open API service indexing awesome lists of open source software.

https://github.com/vzsoares/open-oembed-widgets

Tiny, monochrome, client-side widgets you can embed in Notion or any oEmbed consumer.
https://github.com/vzsoares/open-oembed-widgets

alpinejs bitcoin embed github-pages notion oembed tailwindcss typescript vite widgets

Last synced: 14 days ago
JSON representation

Tiny, monochrome, client-side widgets you can embed in Notion or any oEmbed consumer.

Awesome Lists containing this project

README

          

# ๐Ÿงฉ Open oEmbed Widgets

![License](https://img.shields.io/badge/license-MIT-black)

Tiny, monochrome, **client-side** widgets you can embed in any
[oEmbed](https://oembed.com/) consumer โ€” [Notion](https://notion.so) and others.
No backend โ€” everything runs in the browser and is hosted on GitHub Pages.

**[Open the gallery โ†’](https://vzsoares.github.io/open-oembed-widgets/)** ยท
**[Showcase](https://vzsoares.github.io/open-oembed-widgets/showcase/)** ยท
**[How to use](https://vzsoares.github.io/open-oembed-widgets/help/)**

[![Open oEmbed Widgets gallery](docs/screenshot.png)](https://vzsoares.github.io/open-oembed-widgets/)

Pick a widget, tweak it (theme, options, padding), copy the link, and paste it
into your tool โ€” no account, no code. Widgets are transparent and scale to fit
whatever box they're embedded in.

## ๐Ÿ“ฆ Widgets

| Widget | URL | Description |
| ------------------- | ------------- | ---------------------------------------------------- |
| ๐Ÿ“ˆ Bitcoin Price | `/btc/` | Live BTC/USD price + sparkline, range 1Dโ€“1Y, ~60s. |
| ๐Ÿ’น Crypto Ticker | `/ticker/` | Live price + chart for any coin (`?coin=ethereum`). |
| ๐Ÿ•’ Clock | `/clock/` | Flip or analog clock with date, timezone & 24h opts. |
| ๐ŸŒ World Clock | `/worldclock/`| Current time across several timezones at once. |
| โณ Timer | `/timer/` | Countdown or count-up in days/hours/minutes/seconds. |
| ๐Ÿ“… Day Counter | `/counter/` | Whole days since or until a date (e.g. a deadline). |
| ๐ŸŒ™ Moon Phase | `/moon/` | Current moon phase + illumination, no API. |
| ๐Ÿ–ผ๏ธ Image Rotator | `/images/` | Cross-fades through a list of images on a timer. |
| ๐Ÿ“Š Progress | `/progress/` | Day / week / year / custom (incl. life) progress bar.|
| ๐Ÿ“œ On This Day | `/onthisday/` | Notable historical events for today (Wikipedia). |
| ๐ŸŒค๏ธ Weather | `/weather/` | Current conditions + hi/lo for a place (Open-Meteo). |
| ๐Ÿ™ GitHub Card | `/github/` | A GitHub user or repo card with key stats. |
| ๐Ÿ”— Button List | `/links/` | Link buttons that open in a new tab; custom colors. |
| ๐Ÿ’ฌ Quote | `/quote/` | A quote from a chosen collection (bundled). |
| ๐Ÿ“– Bible Verse | `/bible/` | Random verse in English or Portuguese. |
| ๐Ÿ—“๏ธ Name Day | `/nameday/` | Today's name day(s); 6 locales (CZ/SK/FR/IT/ES/EN). |
| ๐Ÿ“‰ Stocks Ticker | `/stocks/` | Live prices for multiple stocks/ETFs with โ–ฒ/โ–ผ and daily % change. Requires a free [Finnhub](https://finnhub.io/register) key. |
| ๐Ÿ“ˆ Stock Chart | `/stock/` | Live price chart for any stock or ETF, range 1Dโ€“1Y, with hover tooltip and H/L. Requires a free [Finnhub](https://finnhub.io/register) key. |

## ๐Ÿ”— Embed

1. Open the gallery, pick a theme + range, copy the URL
(e.g. `โ€ฆ/open-oembed-widgets/btc/?theme=dark&range=1w`).
2. Paste the link into your tool's embed block
(in Notion: **Create embed**, or type `/embed`).

Widgets have **transparent** backgrounds so they blend into the embedding page.
Each widget page advertises a static oEmbed document via
``, so resolvers like
Notion's (Iframely) get a proper `rich` embed.

### โš™๏ธ Config (query params)

Every widget accepts these **global** options (toggled in the gallery header /
hero, applied to all):

- **Theme** โ€” monochrome, follows the viewer's OS light/dark preference. Pin it
when the iframe context doesn't inherit it: `?theme=dark` / `?theme=light`.
- **Padding** โ€” `?pad=` overrides the widget's inner padding (e.g. `?pad=0`
for edge-to-edge).
- **Scaling** โ€” widgets render at their natural size by default; `?fit=1` scales
them to fill the embed box (text widgets always flow/wrap regardless).

Per-widget options:

- **Range** (BTC) โ€” initial chart window: `?range=1d|1w|1m|3m|1y` (default `1m`).
The range buttons inside the widget stay interactive inside the embed too.
- **Crypto Ticker** โ€” `?coin=ethereum` (any CoinGecko id; default `bitcoin`) and
`?vs=usd` (vs-currency). Same chart/range UI as BTC. Known coins
(BTC/ETH/SOL/โ€ฆ) get Binance + Coinbase fallbacks; any other id is CoinGecko-only.
- **Clock** โ€” `?style=flip|analog` (default `flip`), `?show=time|date|both`
(default `both`), `?seconds=1` for a seconds tile/hand, `?h24=1` for a
24-hour clock (default: locale), and `?tz=Area/City` for an IANA timezone
(default: viewer's local).
- **World Clock** โ€” `?tz=America/Sao_Paulo,Europe/London,Asia/Tokyo` (a
comma-separated list; `local` for the viewer's zone). Labels derive from the
zone's city. Also `?h24=1` and `?seconds=1`. Defaults to Sรฃo Paulo / London /
Tokyo if unset.
- **Timer** โ€” `?mode=down|up` (default `down`). Down counts to `?to=ISO`, up
counts from `?from=ISO` (e.g. `?to=2026-12-31T23:59:59Z`); both default to the
New Year if unset. The gallery's date picker emits the mode-neutral `?date=ISO`
(used when `?to`/`?from` are absent). Also `?units=dhms|dhm`, `?label=...`
caption, and `?done=...` text shown when a countdown hits zero.
- **Day Counter** โ€” `?date=2026-01-01` (a bare date counts in local time) and
`?mode=auto|until|since` (default `auto` picks the direction from the date).
`?label=` adds a caption. Defaults to counting down to the New Year if unset.
- **Moon Phase** โ€” current phase + illumination, computed from the date (no API).
`?date=2026-06-29` pins a specific date for testing/showcase.
- **Image Rotator** โ€” `?src=url1,url2,url3` (comma-separated image URLs; falls
back to bundled demo images if unset), `?mode=sequential|random` (default
`sequential`), `?every=8` seconds per image, and `?fit=cover|contain`
(default `cover`). Hover to pause. `?orient=landscape|portrait` picks the box
shape โ€” the widget fills either; the gallery sizes the preview and copy URL to
match (portrait swaps to 270ร—480). oEmbed advertises the landscape default, so
portrait embeds may need the iframe sized manually in strict oEmbed consumers.
- **Progress** โ€” `?mode=day|week|year|custom` (default `year`). `custom` uses
`?value=&max=`, a `?from=&to=` range, or a birth date + lifespan
(`?from=2000-01-01&years=80`, i.e. life progress). `?label=` overrides the
caption.
- **On This Day** โ€” `?type=selected|events|births|deaths|holidays` (default
`selected`) and `?lang=` Wikipedia language (default `en`). Hit โ†ป for another
event from the day.
- **Weather** โ€” `?city=Tokyo` (geocoded) or `?lat=&lon=`, `?unit=c|f` (default
`c`), `?label=` place-name override. Defaults to London if unset.
- **GitHub Card** โ€” `?user=login` or `?repo=owner/name`. Unauthenticated, so
the public API allows ~60 requests/hour per viewer IP.
- **Button List** โ€” `?btns=Text|https://url|hex` with `;` between buttons (e.g.
`?btns=Site|https://x.com|1d9bf0;Docs|https://x.com/docs`); only http/https/
mailto URLs are allowed. `?layout=list|row` (default `list`).
- **Quote** โ€” `?collection=motivation|wisdom|stoic|tech` (default `motivation`);
quotes are bundled (no API). Hit โ†ป for another.
- **Language** (Bible) โ€” `?lang=en|pt` (default: viewer's locale). EN/PT buttons
stay interactive in the embed.
- **Name Day** โ€” `?lang=cz|sk|fr|it|es|en` (default `cz`). Shows today's name
day(s) from a bundled calendar (no API); the date renders in the locale's own
language. fr/it/es are sanctorale-based (a few days show a feast rather than
personal names); `en` is a loose anglicized set.
- **Stocks Ticker** โ€” `?symbols=NVDA,AAPL,MSFT,SPY` (comma-separated ticker
symbols, default `NVDA,AAPL,MSFT,SPY`) and `?apikey=YOUR_KEY` (required; get a
free key at [finnhub.io](https://finnhub.io/register), no credit card). Shows
symbol ยท price ยท โ–ฒ/โ–ผ ยท daily % change. Refreshes every 60s. When no key is
set the widget shows setup instructions. Note: the key is visible in the embed
URL โ€” the free tier (60 req/min) is fine for personal use.
- **Stock Chart** โ€” `?symbol=AAPL` (default `AAPL`) and `?apikey=YOUR_KEY`
(required; same Finnhub free key). Same chart UI as BTC: large price, change
badge (computed over the selected range), sparkline with hover tooltip, range
buttons 1Dโ€“1Y, and a today's H/L row. Also `?range=1d|1w|1m|3m|1y` (default
`1m`). Works with any US stock or ETF symbol (e.g. `SPY`, `QQQ`, `TSLA`).

The gallery also has a **paste-a-URL** box: paste any widget URL above the cards
to load its theme + options back into the UI for further editing.

## ๐Ÿ—๏ธ Architecture

- **Multi-page** Vite build โ€” one HTML entry per widget gives each a stable
embed URL (`/btc/`).
- **Static oEmbed** โ€” `scripts/gen-oembed.ts` reads `src/widgets/manifest.ts`
and writes `dist//oembed.json` after the Vite build.
- **Resilient data** โ€” the BTC/ticker chart tries CoinGecko โ†’ Binance โ†’ Coinbase
(all public, key-less, CORS-enabled) and uses the first that answers. The
Bible widget uses bible-api.com and falls back to a bundled verse list if the
API is unreachable, so it always renders.
- **Bundled datasets** โ€” Name Day ships an offline `MM-DD โ†’ names` calendar
(`src/widgets/nameday/data.json`) built from the MIT-licensed
[namedays-cs](https://github.com/OzzyCzech/namedays-cs) (cz),
[name-day-calendar](https://github.com/peterknezek/name-day-calendar) (sk), and
[nameday-api](https://github.com/xnekv03/nameday-api) / [nameday.abalin.net](https://nameday.abalin.net)
(fr/it/es/en).
- **No-dependency chart** โ€” a hand-built SVG sparkline (`chart.ts`), monochrome.
- **Config via manifest** โ€” each widget declares `params` (range, language, โ€ฆ);
the gallery renders selectors and bakes them into the embed URL.

```
/
โ”œโ”€โ”€ index.html # widget gallery (home)
# one /index.html per widget: btc, ticker, clock, worldclock, timer, counter,
# moon, images, progress, onthisday, weather, github, links, quote, bible,
# nameday (all embeddable pages)
โ”œโ”€โ”€ btc/index.html
โ”œโ”€โ”€ clock/index.html
โ”œโ”€โ”€ โ€ฆ # progress/, onthisday/, weather/, github/, links/, โ€ฆ
โ”œโ”€โ”€ public/demo/ # bundled demo images for the rotator
โ”œโ”€โ”€ src/
โ”‚ โ”œโ”€โ”€ home.ts # gallery logic (incl. paste-URL import)
โ”‚ โ”œโ”€โ”€ showcase.ts # /showcase/ live-demos page logic
โ”‚ โ”œโ”€โ”€ styles.css # Tailwind + monochrome theme vars
โ”‚ โ”œโ”€โ”€ lib/ # theme.ts, duration.ts, interval.ts (+ *.test.ts)
โ”‚ โ””โ”€โ”€ widgets/
โ”‚ โ”œโ”€โ”€ manifest.ts # widgets + params (single source)
โ”‚ โ”œโ”€โ”€ btc/ # index.ts, price.ts, chart.ts, widget.ts, *.test.ts
โ”‚ โ”œโ”€โ”€ ticker/ # index.ts (reuses btc/price + btc/widget)
โ”‚ โ”œโ”€โ”€ clock/ # index.ts, time.ts, time.test.ts
โ”‚ โ”œโ”€โ”€ worldclock/ # index.ts, worldclock.ts, worldclock.test.ts
โ”‚ โ”œโ”€โ”€ timer/ # index.ts, config.ts, config.test.ts
โ”‚ โ”œโ”€โ”€ counter/ # index.ts, counter.ts, counter.test.ts
โ”‚ โ”œโ”€โ”€ moon/ # index.ts, moon.ts, moon.test.ts
โ”‚ โ”œโ”€โ”€ images/ # index.ts, config.ts, config.test.ts
โ”‚ โ”œโ”€โ”€ progress/ # index.ts, progress.ts, progress.test.ts
โ”‚ โ”œโ”€โ”€ onthisday/ # index.ts, events.ts, events.test.ts
โ”‚ โ”œโ”€โ”€ weather/ # index.ts, weather.ts, weather.test.ts
โ”‚ โ”œโ”€โ”€ github/ # index.ts, github.ts, github.test.ts
โ”‚ โ”œโ”€โ”€ links/ # index.ts, links.ts, links.test.ts
โ”‚ โ”œโ”€โ”€ quote/ # index.ts, quote.ts, quotes.json, quote.test.ts
โ”‚ โ”œโ”€โ”€ bible/ # index.ts, verse.ts, fallback.json, *.test.ts
โ”‚ โ”œโ”€โ”€ nameday/ # index.ts, nameday.ts, data.json, nameday.test.ts
โ”‚ โ”œโ”€โ”€ stocks/ # index.ts, stocks.ts, stocks.test.ts
โ”‚ โ””โ”€โ”€ stock/ # index.ts, stock.ts, stock.test.ts
โ”œโ”€โ”€ e2e/ # Playwright end-to-end specs
โ”œโ”€โ”€ scripts/gen-oembed.ts # post-build oEmbed JSON generator
โ”œโ”€โ”€ playwright.config.ts
โ”œโ”€โ”€ vitest.config.ts
โ””โ”€โ”€ vite.config.js
```

## ๐Ÿ› ๏ธ Develop

Requires [Bun](https://bun.sh).

```bash
bun install
bun run dev # http://localhost:5173 (and /btc/)
bun run test # unit tests (vitest, src/)
bun run test:watch # unit tests in watch mode
bun run test:e2e # Playwright e2e (uses your system Chrome locally)
bun run typecheck # tsc, both app + tooling configs
bun run lint # biome check
bun run format # biome check --write
bun run build # vite build + oEmbed generation -> dist/
bun run preview # serve the production build
```

On push to `main`, CI runs lint, typecheck, unit + e2e tests, and only then
builds and deploys to GitHub Pages (`.github/workflows/deploy.yml`).

## โž• Add a widget

1. Add an entry to `src/widgets/manifest.ts`.
2. Create `/index.html` + `src/widgets//index.ts`.
3. Register the page in `vite.config.js` (`build.rollupOptions.input`).

oEmbed JSON and the gallery card are generated from the manifest. See
[CONTRIBUTING.md](CONTRIBUTING.md) for the full workflow, config-param types,
and the quality checks to run.

## ๐Ÿ“„ License

[MIT](LICENSE) ยท Created by [vzsoares](https://github.com/vzsoares)