OG meta preview cards for web and markdown.
Generate <table>-based HTML cards for GitHub READMEs, releases, and issues:
og-card md https://github.com/runsascoded/img-voronoi https://github.com/hudcostreets/nj-crashes \
--github -w 300Web — React components (demo)
Interactive cards with hover effects, favicons, and automatic GitHub title/description cleaning.
import { OgCardFromUrl } from "og-crd"
import "og-crd/style.css"
<OgCardFromUrl url="https://github.com/runsascoded/img-voronoi" proxy="https://my-proxy.example.com/?url=" />pnpm add og-crdPeer dependencies: react >= 18, react-dom >= 18 (only needed for components; og-crd/core and the CLI work without React).
Import components and their stylesheet:
import { OgCard, OgCardFromUrl, CardRow } from "og-crd"
import "og-crd/style.css"Renders a card with a thumbnail image, title, description, and optional overlay icons.
<OgCard
title="My Project"
description="A short description"
thumbnail="https://example.com/image.png"
href="https://example.com"
/>Without a thumbnail, renders a gradient placeholder showing the title.
| Prop | Type | Default | Description |
|---|---|---|---|
title |
string |
(required) | Card title |
thumbnail |
string | ReactNode |
Image URL or custom element | |
description |
string |
Subtitle text | |
href |
string |
Link URL (wraps card in <a>) |
|
icons |
ReactNode[] |
Icons shown in overlay | |
className |
string |
Additional CSS class | |
aspectRatio |
number |
1.91 |
Card aspect ratio |
hoverEffect |
"scale" | "shadow" | "both" | "none" |
"both" |
Hover animation |
Fetches OG metadata from a URL and renders an OgCard. Shows a skeleton loading state while fetching.
<OgCardFromUrl
url="https://github.com/runsascoded/img-voronoi"
proxy="https://my-proxy.example.com/?url="
/>A proxy is needed in browsers due to CORS. Pass a prefix string (the target URL is appended URL-encoded) or a (url: string) => string function. See cors-prxy for an easy-to-deploy per-project CORS proxy.
GitHub URLs are automatically cleaned: OgCardFromUrl strips "GitHub - owner/repo:" title prefixes and "Contribute to … on GitHub" description boilerplate.
All OgCard props (title, description, thumbnail, etc.) can be passed as overrides.
Horizontal scrolling row for multiple cards.
<CardRow gap="1.5rem">
<div style={{ width: 280 }}><OgCard title="A" thumbnail="..." /></div>
<div style={{ width: 280 }}><OgCard title="B" thumbnail="..." /></div>
</CardRow>For use outside React (Node scripts, build tools, etc.):
import { fetchOgMeta, parseOgTags } from "og-crd/core"
const meta = await fetchOgMeta("https://example.com")
// { title, description, image, siteName, url }The main entry point (og-crd) also re-exports these.
Generate <table>-based card HTML for embedding in GitHub READMEs:
import { fetchOgMeta, renderCard, renderCardRow, renderCardGrid } from "og-crd/core"
const meta = await fetchOgMeta("https://github.com/runsascoded/apvd")
renderCard("https://github.com/runsascoded/apvd", meta, { cleanGitHub: true })
// → <td width="400" valign="top"><a href="..."><img ...><br><b>apvd</b>...</a></td>
// Wrap multiple cards in a <table><tr> row
renderCardRow([{ url, meta }, ...], { width: 400 })
// Multi-row grid
renderCardGrid(cards, { cols: 2, cleanGitHub: true })cleanGitHubTitle and cleanGitHubDescription strip GitHub boilerplate from OG metadata (title prefixes like "GitHub - owner/repo:", description suffixes like "Contribute to … on GitHub"). These are applied automatically by OgCardFromUrl for github.com URLs.
React hook wrapping fetchOgMeta with caching:
const { data, loading, error } = useOgMeta(url, proxy)og-card <url> [url2 ...] [options]| Flag | Description |
|---|---|
-f, --field <name> |
Output one field: title, description, image, siteName, url |
-j, --json |
JSON output |
-p, --proxy <url> |
CORS proxy prefix |
-P, --parallel <n> |
Max concurrent fetches (default: 5) |
# Human-readable output
og-card https://example.com
# Just the image URL
og-card https://example.com -f image
# JSON, multiple URLs
og-card https://a.com https://b.com --json
# From stdin
echo "https://example.com" | og-card --json4-column grid example:
og-card md https://github.com/HackJerseyCity/jc-taxes https://github.com/hudcostreets/path \
https://github.com/hudcostreets/hudson-transit https://github.com/runsascoded/apvd \
--github -w 200 --cols 4# More examples
og-card md url1 url2 --row # Force single-row layout
og-card md url1 -f image # Markdown image link: [](url)
og-card md url1 -f html # Raw <td> cells (no <table> wrapper)
og-card md url1 --no-desc --no-title # Image only| Flag | Description |
|---|---|
-c, --cols <n> |
Cards per row (default: 2) |
-f, --format <type> |
table (default), image, html |
-r, --row |
Wrap in <table><tr> |
-w, --width <px> |
Card width (default: 400) |
--no-desc |
Omit description |
--no-title |
Omit title |
-g, --github |
Strip GitHub boilerplate |
-p, --proxy <url> |
CORS proxy prefix |
-P, --parallel <n> |
Max concurrent fetches (default: 5) |
Override CSS custom properties on .og-card:
.og-card {
--og-card-radius: 8px;
--og-card-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
--og-card-shadow-hover: 0 8px 24px rgba(0, 0, 0, 0.25);
--og-card-overlay-bg: linear-gradient(transparent 40%, rgba(0, 0, 0, 0.85));
--og-card-title-color: #fff;
--og-card-desc-color: rgba(255, 255, 255, 0.85);
--og-card-placeholder-bg: linear-gradient(135deg, #667eea, #764ba2);
--og-card-skeleton-bg: rgba(128, 128, 128, 0.2);
--og-card-transition: 0.2s ease;
}OgCardFromUrl fetches pages client-side, so a CORS proxy is needed. This project uses cors-prxy to deploy a per-project proxy (Cloudflare Worker or Lambda) with a strict allowlist:
{
"name": "og-crd",
"allow": [
{ "domain": "github.com", "paths": [
"/runsascoded/*",
"/hudcostreets/*",
"/HackJerseyCity/*"
]}
],
"cors": {
"origins": ["https://og-crd.rbw.sh", "http://localhost:*"]
}
}pnpm add -D cors-prxy
cors-prxy deploy # creates Cloudflare Worker (or Lambda)
cors-prxy status # shows endpoint URLThe endpoint URL is set as VITE_CORS_PROXY_URL (env var for local dev, GitHub repo variable for CI builds).
pnpm dev # Demo site at localhost:3847
pnpm build # Library build → dist/
pnpm build:watch # Rebuild on changes
pnpm demo:build # Production demo build → demo/dist/