1- # HowlCard - OpenGraph Cards Rendered on the Edge
1+ # MrDemonWolf OG Tool - OpenGraph Cards in Your Browser
22
3- HowlCard is a config-driven OpenGraph card generator that renders
4- 1200x630 PNG social cards on Cloudflare Workers. Templates are pure
5- TypeScript functions that emit SVG, themes carry every brand value
6- (colors, fonts, byline), and a built-in playground lets you preview
7- and download cards or point ` og:image ` straight at a URL. Extracted
8- from the build-time card system on mrdemonwolf.com.
3+ MrDemonWolf OG Tool generates 1200x630 OpenGraph social cards for
4+ mrdemonwolf.com, rendered entirely in the browser and hosted as a
5+ static site on GitHub Pages. Paste a blog, service, or portfolio URL
6+ and it pulls the title, category, and featured image through the
7+ WordPress REST API; the card design follows the page type
8+ automatically. Extracted from the build-time card system on
9+ mrdemonwolf.com.
910
1011Design in code. Ship cards that howl.
1112
1213## Features
1314
14- - ** Three starter templates** - ` default ` (brand howl card), ` blog `
15- (photo background, category chip, wrapped title, byline), and
16- ` project ` (eyebrow, tag chip, case-study framing), ported
17- pixel-identical from mrdemonwolf.com.
18- - ** Themes over hardcoding** - every color and text value lives in a
19- ` Theme ` ; four built in (` default ` , ` ember ` , ` forest ` , ` mono ` ), new
20- ones are a single object in ` packages/core/src/theme.ts ` .
21- - ** Edge rendering** - ` @resvg/resvg-wasm ` rasterizes SVG to PNG
22- inside the Worker; no native binaries, no build step per card.
23- - ** Playground** - the Worker's ` / ` route serves a live editor: pick
24- template and theme, type the fields, preview, download.
25- - ** URL API** - ` /og.png?template=blog&theme=default&title=... ` is a
26- stable image URL you can use directly in ` og:image ` tags.
27- - ** Remote image embedding** - ` image= ` query param fetches a photo
28- server-side (no Referer, so hotlink-protected hosts work) and
29- embeds it; failures fall back to the text-only card.
15+ - ** Page-type presets** - the design is decided by what the page is:
16+ ` blog ` (photo, category chip, wrapped title, byline), ` portfolio `
17+ (The build eyebrow, tag chip), ` service ` (Services eyebrow), and
18+ ` default ` (brand howl card). No theme fiddling.
19+ - ** Pull from URL** - paste a mrdemonwolf.com URL; the tool detects
20+ the page type from the path and fills title, chip label, and
21+ featured image via the WordPress REST API (CORS-open by default).
22+ - ** Browser rendering** - ` @resvg/resvg-wasm ` rasterizes SVG to PNG
23+ client-side; nothing leaves your machine, no server to deploy.
24+ - ** Image drop fallback** - WordPress media files usually block
25+ cross-origin fetches, so the tool accepts a dropped or chosen
26+ image file whenever the direct fetch fails.
27+ - ** Static deploy** - plain Vite build pushed to GitHub Pages by the
28+ bundled Actions workflow on every push to ` main ` .
3029
3130## Getting Started
3231
33321 . Clone the repository:
3433 ``` bash
35- git clone https://github.com/mrdemonwolf/howlcard .git
36- cd howlcard
34+ git clone https://github.com/mrdemonwolf/mrdemonwolf-og-tool .git
35+ cd mrdemonwolf-og-tool
3736 ```
38372 . Install dependencies:
3938 ``` bash
4039 npm install
4140 ```
42- 3 . Start the local playground :
41+ 3 . Start the dev server :
4342 ``` bash
4443 npm run dev
4544 ```
46- 4 . Open ` http:// localhost:8787 ` and build a card.
45+ 4 . Open the printed localhost URL and build a card.
4746
4847## Usage
4948
50- Render a card by URL (all params optional except ` template ` fields):
51-
52- ``` bash
53- # Brand card, default theme
54- /og.png? template=default
55-
56- # Blog card with a category chip and a background photo
57- /og.png? template=blog& theme=default& title=My%20Post%20Title& label=WordPress& image=https://example.com/photo.jpg
58-
59- # Project card with the "The build" eyebrow and a tag chip
60- /og.png? template=project& title=Aurum%20Contracting& label=WordPress
61- ```
62-
63- Point a page's OpenGraph tag at the deployed Worker:
64-
65- ``` html
66- <meta property =" og:image" content =" https://howlcard.<your-subdomain>.workers.dev/og.png?template=blog&title=Hello" />
67- ```
68-
69- Endpoints:
49+ 1 . Paste a page URL (for example
50+ ` https://www.mrdemonwolf.com/blog/my-post/ ` ) and click ** Pull** .
51+ 2 . Adjust the title or chip label if wanted; the preview re-renders
52+ as you type.
53+ 3 . If the featured image could not be fetched (most WordPress hosts
54+ block cross-origin media reads), save it from the site and drop
55+ the file onto the image box.
56+ 4 . Click ** Download PNG** and upload the file to WordPress (Rank
57+ Math social image, or the media library).
7058
71- | Route | Purpose |
72- | --------- | ---------------------------------------------- |
73- | ` / ` | Playground (template picker, preview, download) |
74- | ` /og.png ` | PNG renderer (query-param driven) |
75- | ` /health ` | JSON status and template list |
59+ The live tool deploys to
60+ ` https://mrdemonwolf.github.io/mrdemonwolf-og-tool/ ` .
7661
7762## Tech Stack
7863
79- | Layer | Technology |
80- | ---------- | --------------------------------- |
81- | Runtime | Cloudflare Workers |
82- | Framework | Hono |
83- | Rendering | @resvg/resvg-wasm (SVG to PNG) |
84- | Templates | TypeScript SVG functions |
85- | Fonts | DM Sans, JetBrains Mono (vendored TTF) |
86- | Tooling | npm workspaces, Wrangler, tsx |
64+ | Layer | Technology |
65+ | --------- | --------- --------------------------------- |
66+ | Hosting | GitHub Pages (Actions deploy) |
67+ | Bundler | Vite |
68+ | Rendering | @resvg/resvg-wasm (SVG to PNG, in-browser) |
69+ | Data | WordPress REST API ( ` /wp-json/wp/v2/ ` ) |
70+ | Templates | TypeScript SVG functions |
71+ | Fonts | DM Sans, JetBrains Mono (vendored TTF) |
8772
8873## Development
8974
9075### Prerequisites
9176
9277- Node.js 20 or newer
9378- npm 10 or newer
94- - A Cloudflare account (for ` npm run deploy ` )
9579
9680### Setup
9781
@@ -110,44 +94,40 @@ Endpoints:
11094
11195### Development Scripts
11296
113- - ` npm run dev ` - Wrangler dev server for the playground and API
114- - ` npm run deploy ` - deploy the Worker to Cloudflare
115- - ` npm run check ` - type-check all workspaces and run the core
116- self- check (renders every template under every theme)
97+ - ` npm run dev ` - Vite dev server
98+ - ` npm run build ` - production build into ` dist/ `
99+ - ` npm run preview ` - serve the production build locally
100+ - ` npm run check` - type-check and run the template self-check
117101- ` npm run check-types ` - type-check only
118102
119103### Code Quality
120104
121- - Strict TypeScript across both workspaces
122- - A runnable self-check in ` @howlcard/core ` guards template output
123- ( well-formed SVG, theme colors present, escaping, title wrapping)
105+ - Strict TypeScript
106+ - A runnable self-check renders every page type and guards
107+ well-formed SVG, escaping, eyebrow text, and title wrapping
124108- Fonts load as buffers, never file paths (resvg renders no text on
125109 a missed path)
126110
127111## Project Structure
128112
129113```
130- howlcard/
131- ├── apps/
132- │ └── web/ # Cloudflare Worker (Hono)
133- │ ├── src/
134- │ │ ├── index.ts # routes: /, /og.png, /health
135- │ │ ├── render.ts # resvg-wasm rasterizer + image fetcher
136- │ │ ├── playground.ts # served playground page
137- │ │ └── fonts/ # vendored TTFs (DM Sans, JetBrains Mono)
138- │ └── wrangler.jsonc
139- └── packages/
140- └── core/ # pure template + theme engine (no I/O)
141- └── src/
142- ├── templates.ts # default / blog / project
143- ├── theme.ts # Theme type + built-in themes
144- ├── svg.ts # esc, wrapTitle, chip, wolf mark
145- └── selfcheck.ts # runnable output guard
114+ mrdemonwolf-og-tool/
115+ ├── index.html # the app shell (form + preview)
116+ ├── src/
117+ │ ├── main.ts # UI wiring: pull, drop, render, download
118+ │ ├── templates.ts # page-type presets (blog/portfolio/service/default)
119+ │ ├── theme.ts # brand values (v6 Brand Blues)
120+ │ ├── svg.ts # esc, wrapTitle, chip, wolf mark
121+ │ ├── wp.ts # WordPress REST pull by URL
122+ │ ├── render.ts # resvg-wasm rasterizer + image helpers
123+ │ ├── selfcheck.ts # runnable template guard
124+ │ └── fonts/ # vendored TTFs
125+ └── .github/workflows/pages.yml # build + deploy to GitHub Pages
146126```
147127
148128## License
149129
150- ![ GitHub license] ( https://img.shields.io/github/license/mrdemonwolf/howlcard .svg?style=for-the-badge&logo=github )
130+ ![ GitHub license] ( https://img.shields.io/github/license/mrdemonwolf/mrdemonwolf-og-tool .svg?style=for-the-badge&logo=github )
151131
152132## Contact
153133
0 commit comments