feat: static API endpoints for extension support#92
Conversation
- Enable Next.js static export (output: export) - Remove free API routes (paid API coming to api.thesvg.org) - Remove API docs page and components - Remove dynamic OG image generation, use static fallback - Convert RSS feed to build-time generation - Add Cloudflare Pages cache headers - Update all navigation links and references - Set dynamicParams=false for static export compatibility - Fix PostHog init for static export (client-side provider) - Disable icon link prefetch to prevent RSC 404s - Fix variant switch flicker on icon detail page - Remove Vercel-specific configuration Co-Authored-By: Glinr <bot@glincker.com>
…rate PostHog to instrumentation - Fix kbd shortcut hydration error by deferring isMac detection to useEffect - Eliminate redundant SVG fetches in download and PNG export by reusing cached svgContent - Move PostHog init to instrumentation-client.ts (Next.js 15.3+), remove dead provider component - Add PostHog tracking to detail page actions (PNG export, quick commands, jsdelivr, share) Co-Authored-By: Glinr <bot@glincker.com>
- Fix duplicate function signatures in jsdelivr-button and quick-commands from merge - Add missing svgContent dependency in png-export useCallback - Use useSyncExternalStore for isMac detection to avoid setState-in-effect warning
Generate static JSON files at build time (registry.json, categories.json, per-icon detail files) so Raycast and other extensions can fetch data from the static export without needing dynamic API routes. Co-Authored-By: Glinr <bot@glincker.com>
There was a problem hiding this comment.
Pull request overview
This PR restores extension-facing “API” functionality for the static-exported site by generating equivalent JSON endpoints at build time, while also adjusting a few client utilities to better operate on inline SVG content.
Changes:
- Add a build-time generator to emit static JSON API files under
public/api/(registry, categories, per-icon detail). - Run API generation automatically during
pnpm buildand ignore generated output in Git. - Update SVG download/PNG export flows to accept inline SVG markup (and add a few new PostHog capture events), alongside replacing the PostHog provider with
instrumentation-client.ts.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/scripts/generate-api.ts |
New script that generates public/api/* JSON files from src/data/icons.json. |
package.json |
Runs the generator before next build. |
.gitignore |
Ignores generated public/api/ and scopes /scripts/ ignore to repo root only. |
src/lib/svg-to-png.ts |
Allows PNG conversion from either raw SVG markup or a URL. |
src/components/icons/icon-detail-page.tsx |
Reuses fetched SVG content for SVG download and passes inline SVG to PNG export. |
src/components/icons/detail/png-export.tsx |
Uses inline SVG when available and captures a PostHog event on export. |
src/components/icons/detail/quick-commands.tsx |
Captures PostHog event on copy. |
src/components/icons/detail/jsdelivr-button.tsx |
Captures PostHog event on copy. |
src/components/blog/share-buttons.tsx |
Captures PostHog events for copy/share clicks. |
src/components/search/search-bar.tsx |
Updates Mac detection to avoid SSR hydration mismatch. |
src/components/header.tsx |
Same Mac detection update as search bar. |
src/app/layout.tsx |
Removes PostHogProvider usage. |
instrumentation-client.ts |
New PostHog initialization entrypoint. |
src/components/posthog-provider.tsx |
Removes the old PostHog provider component. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| function readSvgFile(relativePath: string): string { | ||
| const fullPath = join(ROOT, "public", relativePath); | ||
| if (!existsSync(fullPath)) return ""; | ||
| try { | ||
| return readFileSync(fullPath, "utf-8").trim(); | ||
| } catch { | ||
| return ""; | ||
| } |
There was a problem hiding this comment.
readSvgFile() uses join(ROOT, "public", relativePath), but icons.json variant paths start with a leading / (e.g. /icons/...). In Node, path.join() discards prior segments when a later segment is absolute, so this will resolve to /icons/... and the SVG files won’t be found, causing svg fields to be empty in the generated per-icon JSON. Strip the leading slash (or otherwise normalize to a relative path) before joining so the script reads from <repo>/public/icons/....
Greptile SummaryThis PR adds a build-time static JSON API generator ( Confidence Score: 5/5Safe to merge — all findings are minor P2 style suggestions with no correctness or reliability impact. The implementation is correct: the script reads src/scripts/generate-api.ts — minor: wrong doc comment path, omitted aliases in detail output, and misleading limit/count fields in registry.json Important Files Changed
Sequence DiagramsequenceDiagram
participant Dev as Developer
participant Build as pnpm build
participant Script as generate-api.ts
participant FS as Filesystem
participant CF as Cloudflare Pages
participant Ext as Raycast Extension
Dev->>Build: pnpm build
Build->>Script: tsx src/scripts/generate-api.ts
Script->>FS: Read src/data/icons.json
FS-->>Script: Icon entries
Script->>FS: Write public/api/registry.json
Script->>FS: Write public/api/categories.json
Script->>FS: Write public/api/registry/slug.json (per icon)
Script-->>Build: exit 0
Build->>CF: next build → out/ (includes public/api/)
CF-->>Ext: GET /api/registry.json → 200 JSON
CF-->>Ext: GET /api/registry/github.json → 200 JSON
CF-->>Ext: GET /api/categories.json → 200 JSON
Reviews (1): Last reviewed commit: "feat: add static API generation for exte..." | Re-trigger Greptile |
- Strip leading slash in readSvgFile for safe path.join - Clean public/api/ before regeneration to remove stale files - Add aliases to per-icon detail output - Remove redundant count/limit from registry.json - Fix doc comment path to match actual file location - Guard PostHog init with runtime key check, add fallback host - Remove unused useState import in search-bar Co-Authored-By: Glinr <bot@glincker.com>
Keep runtime PostHog guard and unused useState removal from branch. Co-Authored-By: Glinr <bot@glincker.com>
Summary
src/scripts/generate-api.ts)public/api/registry.json,public/api/categories.json, and per-icon detail files atpublic/api/registry/<slug>.jsonnext build.gitignoreto scope/scripts/to root only and ignore generatedpublic/api/Why
The Cloudflare static export removed dynamic API routes, breaking the Raycast extension (404 errors). This generates equivalent static JSON files at build time so extensions can fetch data from the deployed site.
Test plan
pnpm buildsucceeds and generatesout/api/registry.jsoncurl https://thesvg.org/api/registry.jsonreturns icon list after deploycurl https://thesvg.org/api/registry/github.jsonreturns icon detail with inline SVGscurl https://thesvg.org/api/categories.jsonreturns category list