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.
- Host: GitHub
- URL: https://github.com/vzsoares/open-oembed-widgets
- Owner: vzsoares
- License: mit
- Created: 2026-05-26T15:42:32.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-05-26T23:15:14.000Z (about 1 month ago)
- Last Synced: 2026-05-26T23:20:15.746Z (about 1 month ago)
- Topics: alpinejs, bitcoin, embed, github-pages, notion, oembed, tailwindcss, typescript, vite, widgets
- Language: TypeScript
- Homepage: https://vzsoares.github.io/open-oembed-widgets/
- Size: 145 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# ๐งฉ Open oEmbed Widgets

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/)**
[](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)