readme-SVG-youtube-preview turns any YouTube URL into a clickable, styled SVG card you can drop into any GitHub README, Markdown file, or webpage.
[](https://youtube.com/watch?v=dQw4w9WgXcQ)The thumbnail is embedded as base64 inside the SVG — so it renders perfectly inside GitHub README without being blocked by GitHub's image proxy.
- Features
- Tech Stack
- Technical Notes
- Getting Started
- Testing
- Deployment
- Usage
- Configuration
- License
- Contacts
- ❤️ Support the Project
- YouTube URL parsing that doesn’t flake out
- Supports raw 11-char IDs and common formats (
watch?v=,youtu.be,embed,shorts).
- Supports raw 11-char IDs and common formats (
- Zero API key dependency
- Pulls title/thumbnail metadata via public YouTube oEmbed endpoint.
- GitHub-compatible SVG output
- Can embed thumbnail as base64 data URI to bypass GitHub SVG external image restrictions.
- Highly tweakable card rendering
- Width, radius, title opacity, plate opacity, border styling, title placement.
- Multiple title layouts
overlay_top,overlay_bottom,outside_top,outside_bottom(plus aliases).
- Fast, stateless HTTP API
/badgefor SVG rendering,/infofor metadata probing.
- Cache-friendly responses
Cache-Control: public, max-age=3600out of the box.
- Built-in browser UI
- Local playground (
/) for live config tweaking + instant Markdown/HTML snippet generation.
- Local playground (
- Language: Python (runtime-compatible with Vercel Python serverless)
- Backend framework: Flask
- HTTP layer:
urllib.request(standard lib) - Serving model: Vercel serverless via
@vercel/python - Frontend: vanilla HTML/CSS/JS (
index.html,styles.css,app.js) - Process server (non-serverless environments): Gunicorn
.
├── api/
│ ├── __init__.py
│ ├── index.py # Flask app + routes (/ , /badge, /info)
│ └── card.py # SVG generation + base64 image embedding
├── app.js # Frontend logic for generator UI
├── index.html # Generator UI markup
├── styles.css # UI styling
├── requirements.txt # Python dependencies
├── vercel.json # Vercel build/routes config
├── LICENSE
└── README.md
-
oEmbed over official YouTube Data API
Keeps onboarding friction low: no API keys, no quota setup, no credential handling. -
Base64 thumbnail embedding as first-class behavior
GitHub markdown rendering strips/blocks external image references in SVGs, so embedding image payload into SVG is the pragmatic fix. -
Server-side SVG composition instead of static templates
Dynamic query parameters let users style cards without forking the project or editing assets. -
Hard parameter clamping
Width/radius/opacity/border values are constrained to sane ranges to prevent broken output and tame weird inputs. -
Two-route API shape
/infofor metadata/debugging and/badgefor render output keeps responsibilities clean and DX nicer.
Install the following before hacking locally:
- Python
3.10+ pip- (Optional) virtualenv tooling (
python -m venv) - (Optional) Vercel CLI for cloud deploy testing
# 1) Clone your fork (or upstream if you're just evaluating)
git clone https://github.com/readme-SVG/readme-SVG-youtube-preview.git
cd readme-SVG-youtube-preview
# 2) Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate
# 3) Install dependencies
pip install -r requirements.txt
# 4) Run Flask app locally (from repository root)
flask --app api.index run --debugLocal app should be available at:
http://127.0.0.1:5000
This repo currently has no formal unit/integration test suite checked in. Current baseline validation is smoke-style endpoint checks.
Use these commands locally:
# Syntax sanity for Python modules
python -m compileall api
# Run local server in one terminal
flask --app api.index run --debug
# In another terminal: metadata endpoint smoke test
curl "http://127.0.0.1:5000/info?id=dQw4w9WgXcQ"
# SVG render smoke test (writes output for manual inspection)
curl "http://127.0.0.1:5000/badge?id=dQw4w9WgXcQ" -o /tmp/card.svgIf you’re extending functionality, add tests in your PR (recommended: pytest) and document the command in your PR description.
# Install CLI once
npm i -g vercel
# Deploy interactively
vercelvercel.json already wires all routes to api/index.py, including root UI and API endpoints.
pip install -r requirements.txt
gunicorn -w 2 -b 0.0.0.0:8000 "api.index:app"Then expose via reverse proxy (Nginx/Caddy/Cloud LB) as needed.
No CI pipeline is currently committed. For production-grade workflows, add:
- lint + format checks
- API smoke tests
- deploy preview per PR
- protected main branch with required checks
# Swap BASE_URL with your deployed domain and VIDEO_ID with actual YouTube ID
[](https://youtube.com/watch?v=VIDEO_ID)# Useful when you already have full YouTube links in scripts/content tooling
[](https://youtube.com/watch?v=dQw4w9WgXcQ)# Example with dark palette, outside title plate, and visible border
[](https://youtube.com/watch?v=dQw4w9WgXcQ)GET /badge?id=<VIDEO_ID>
GET /badge?url=<YOUTUBE_URL>
GET /info?id=<VIDEO_ID>
GET /info?url=<YOUTUBE_URL>
This project is currently mostly config-via-query-params (no mandatory .env variables).
idorurl(required, one of them)width(default320, clamped200..600)radius(default10, clamped0..30)bg(default0f1117)title_color(defaultffffff)title_opacity(default1, clamped0..1)plate_color(default0f1117)plate_opacity(default0.78, clamped0..1)title_position(overlay_top,overlay_bottom,outside_top,outside_bottom; aliases supported)border_width(default1, clamped0..10)border_color(defaultffffff)embed(trueby default; setembed=falseto skip base64 embedding)
No required runtime env vars are hardcoded in the current code path. If you add config, keep .env.example in sync and document every key here.
Distributed under the Apache-2.0 License. See LICENSE.
- GitHub org:
readme-SVG - Maintainer profile:
OstinUA - Issues: https://github.com/readme-SVG/readme-SVG-youtube-preview/issues
If you find this tool useful, consider leaving a ⭐ on GitHub or supporting the author directly: