Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [main, dev]
branches: [production, dev]
pull_request:
branches: [main, dev]
branches: [production, dev]

jobs:
build:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/pr-target-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ name: PR Target Check

on:
pull_request:
branches: [main]
branches: [production]

jobs:
check-source-branch:
runs-on: ubuntu-latest
steps:
- name: Only allow PRs from dev to main
- name: Only allow PRs from dev to production
if: github.head_ref != 'dev'
run: |
echo "::error::PRs targeting 'main' are only allowed from the 'dev' branch."
echo "::error::PRs targeting 'production' are only allowed from the 'dev' branch."
echo "Please target 'dev' instead, or merge your branch into 'dev' first."
echo ""
echo " Source: ${{ github.head_ref }}"
echo " Target: ${{ github.base_ref }}"
exit 1
- name: PR source branch is valid
if: github.head_ref == 'dev'
run: echo "PR from 'dev' to 'main' — allowed."
run: echo "PR from 'dev' to 'production' — allowed."
80 changes: 60 additions & 20 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
# CLAUDE.md — OGCOPS

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What is this?
OGCOPS is a free, open-source OG image generator and social media preview checker. Built with Astro + React Islands, deployed to Vercel.
OGCOPS is a free, open-source OG image generator and social media preview checker. Built with Astro SSR + React Islands, deployed to Vercel at og.codercops.com. GitHub: github.com/codercops/ogcops. MIT licensed.

## Commands
```bash
npm run dev # Start dev server
npm run build # Production build
npm run preview # Preview production build
npm run test # Run vitest
npm run test:watch # Watch mode
npm run check # Type-check (astro check + tsc)
npm run dev # Start dev server (port 4321)
npm run build # Production build
npm run preview # Preview production build
npm run test # Run vitest (single run)
npm run test:watch # Watch mode
npm run test:ui # Vitest UI
npm run check # Type-check (astro check + tsc --noEmit)
npm run lint # Astro linting
npm run generate:favicons # Generate favicon assets
```

## Architecture
Expand All @@ -19,20 +24,32 @@ npm run check # Type-check (astro check + tsc)
- **Satori** runs client-side for instant SVG preview (zero server calls during editing)
- **Satori + resvg-wasm** runs server-side for PNG generation (`/api/og`)
- **No database** — state lives in URL query params + client-side useReducer
- **CORS-open API** for developer use
- **CORS-open API** — no API key, no rate limits

## Key Directories
- `src/templates/` — 109 templates across 12 categories. Each template is a `.ts` file exporting a `TemplateDefinition`.
- `src/lib/` — Core engine (og-engine.ts, font-loader.ts, meta-fetcher.ts, meta-analyzer.ts)
- `src/templates/` — 120 templates across 12 categories. Each is a `.ts` file exporting a `TemplateDefinition`.
- `src/lib/` — Core engine (og-engine.ts, font-loader.ts, meta-fetcher.ts, meta-analyzer.ts, api-validation.ts)
- `src/components/editor/` — React components for the OG image editor
- `src/components/preview/` — React components for the social media preview checker
- `src/pages/api/` — API endpoints (og, preview, templates)
- `src/pages/api/` — API endpoints
- `src/styles/` — CSS files (global.css, editor.css, preview.css, api-docs.css)
- `public/fonts/` — Bundled .woff fonts (Inter, Playfair Display, JetBrains Mono)
- `tests/` — Vitest tests (api/, lib/, templates/)

## Conventions
- CSS custom properties only (no Tailwind). Accent: `#E07A5F`.
- TypeScript strict mode. Path alias `@/*` → `src/*`.
- Fonts bundled as `.woff` in `public/fonts/`.
- Templates follow `TemplateDefinition` interface in `src/templates/types.ts`.
## Pages & API Endpoints

**Pages:**
- `/` — Homepage
- `/create/` — OG image editor
- `/templates` — Template gallery
- `/preview` — Social media preview checker
- `/api-docs` — API documentation

**API (all CORS-open, no auth):**
- `GET /api/og?template={id}&...` — Generate PNG (1200x630, 24h cache)
- `GET /api/preview?url={url}` — Fetch and analyze a URL's meta tags
- `GET /api/templates` — List all templates as JSON
- `GET /api/templates/[id]/thumbnail.png` — Template thumbnail (1-week cache)

## Reference Files
- Template interface: `src/templates/types.ts`
Expand All @@ -42,19 +59,42 @@ npm run check # Type-check (astro check + tsc)
- API validation schemas: `src/lib/api-validation.ts`
- Template registry: `src/templates/registry.ts`

## Template Contribution
1. Create `src/templates/{category}/{id}.ts`
2. Export a `TemplateDefinition`
3. Register in `src/templates/{category}/index.ts`
## Template System

120 templates across 12 categories: blog, product, saas, github, event, podcast, developer, newsletter, quote, ecommerce, job, tutorial.

**Adding a template:**
1. Create `src/templates/{category}/{id}.ts` exporting a `TemplateDefinition`
2. Register in `src/templates/{category}/index.ts`
3. Add import + registration in `src/templates/registry.ts`
4. Run `npm run test` to verify

**Template field types:** text, textarea, color, select, number, toggle, image.
**Field groups:** Content, Style, Brand.

## Conventions
- CSS custom properties only (no Tailwind). Accent: `#E07A5F`.
- TypeScript strict mode. Path alias `@/*` → `src/*`.
- Fonts bundled as `.woff` in `public/fonts/` (Inter Regular/Medium/SemiBold/Bold, Playfair Display Regular/Bold, JetBrains Mono Regular/Bold).
- Node 22 (`.nvmrc`).
- Testing: Vitest with node environment. Tests in `tests/**/*.test.ts`. Globals enabled.

## CI/CD
- Runs on push to `production`/`dev` and PRs to those branches
- Steps: `npm run check` → `npm run test` → `npm run build`
- **Branch strategy:** `dev` is the default branch. PRs target `dev`. Releases go `dev` → `production`. Direct PRs to `production` are blocked unless from `dev`.

## Environment Variables (`.env.local`, all optional)
- `UPSTASH_REDIS_REST_URL`, `UPSTASH_REDIS_REST_TOKEN` — Optional visitor counter

## Gotchas / Constraints
- Satori does **not** support CSS grid — only flexbox
- Every `div` must have `display: 'flex'` explicitly in its style
- No CSS classes in satori JSX — inline styles only
- Font files must be listed in `astro.config.mjs` `includeFiles` array for Vercel deployment
- WASM imports need `optimizeDeps.exclude` in the Vite config
- `renderToPng` returns `ArrayBuffer` (not `Buffer`) for `BodyInit` compatibility
- Canvas is always 1200x630px

## Do NOT
- Add Tailwind CSS — the project uses CSS custom properties only
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ npm run build # Full production build
1. Fork the repo and create a branch: `git checkout -b feat/my-feature`
2. Make your changes
3. Ensure `npm run check` and `npm run test` pass
4. Push and open a PR against `main`
4. Push and open a PR against `dev`
5. Fill out the [PR template](.github/PULL_REQUEST_TEMPLATE.md) — screenshots are required for visual changes
6. Wait for review

Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ OGCOPS is different:
## Quick Start

```bash
git clone https://github.com/codercops/ogcops.git
git clone -b dev https://github.com/codercops/ogcops.git
cd ogcops
npm install
npm run dev
Expand Down Expand Up @@ -114,6 +114,16 @@ The build output in `dist/` can be deployed to any Node.js hosting platform.

Contributions are welcome — templates, bug fixes, features, docs, and more. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and guidelines.

> **Important:** Always fork and branch from `dev` (the default branch). The `production` branch is for releases only. PRs targeting `production` directly will be closed.

```bash
# Fork the repo on GitHub, then:
git clone https://github.com/<your-username>/ogcops.git
cd ogcops
git checkout dev
git checkout -b your-feature-branch
```

- [Open an issue](https://github.com/codercops/ogcops/issues) — bug reports and feature requests
- [Start a discussion](https://github.com/codercops/ogcops/discussions) — questions, ideas, show & tell

Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ The following are **out of scope:**

| Version | Supported |
|---------|-----------|
| Latest (main branch) | Yes |
| Latest (production branch) | Yes |
| Older releases | No |

## Recognition
Expand Down
1 change: 1 addition & 0 deletions src/components/Footer.astro
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const year = new Date().getFullYear();
<a href="/templates">Templates</a>
<a href="/api-docs">API Docs</a>
<a href="https://github.com/codercops/ogcops" target="_blank" rel="noopener">GitHub</a>
<a href="https://github.com/codercops/ogcops/issues/new?labels=feedback&title=Feedback:&body=<!-- Describe your feedback here -->" target="_blank" rel="noopener">Feedback</a>
</nav>
</div>

Expand Down
Loading