Skip to content

Commit 9f54a7c

Browse files
feat!: rename to mrdemonwolf-og-tool, go static on GitHub Pages
BREAKING CHANGE: the Cloudflare Workers app (Hono + server-side rendering, howlcard name) is replaced by a single static Vite app. Rendering moves into the browser via @resvg/resvg-wasm, so GitHub Pages can host it with zero server. Theme picker replaced by page-type presets (blog / portfolio / service / default): the design follows what the page is. New Pull-from-URL: detects the page type from a mrdemonwolf.com path and fills title, chip, and featured image through the WordPress REST API (CORS-open); media files usually are not, so an image drop fallback covers that. Deploys via the bundled Pages workflow on push to main. Verified: selfcheck 4 page types, vite build clean, in-browser render 1200x630, live pull against production WordPress fills title + category. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent f56caa2 commit 9f54a7c

30 files changed

Lines changed: 1431 additions & 1334 deletions

.github/workflows/pages.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: pages
15+
cancel-in-progress: true
16+
17+
jobs:
18+
deploy:
19+
runs-on: ubuntu-latest
20+
environment:
21+
name: github-pages
22+
url: ${{ steps.deployment.outputs.page_url }}
23+
steps:
24+
- uses: actions/checkout@v4
25+
- uses: actions/setup-node@v4
26+
with:
27+
node-version: 22
28+
cache: npm
29+
- run: npm ci
30+
- run: npm run check
31+
- run: npm run build
32+
- uses: actions/configure-pages@v5
33+
- uses: actions/upload-pages-artifact@v3
34+
with:
35+
path: dist
36+
- id: deployment
37+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
node_modules/
22
dist/
3-
.wrangler/
4-
.dev.vars
53
*.log
64
.DS_Store

README.md

Lines changed: 65 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,81 @@
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

1011
Design 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

3332
1. 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
```
3837
2. 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

apps/web/package.json

Lines changed: 0 additions & 22 deletions
This file was deleted.

apps/web/src/globals.d.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

apps/web/src/index.ts

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)