Static site for SharpEmu — landing page and PS5 game compatibility database. Built with Astro + Tailwind, deployed on Cloudflare Pages.
npm install
npm run dev # dev server (Pagefind search 404s in dev — build first)
# /downloads fetches GitHub releases at build time; set GITHUB_TOKEN to avoid
# anonymous rate limits: GITHUB_TOKEN=$(gh auth token) npm run build
npm test # vitest
npm run build # static build into dist/ + Pagefind index
npm run preview # serve dist/src/data/games.json is generated — do not edit imported game metadata by hand.
The supported exception is the optional "commentsDisabled": true per-game
override; imports preserve this setting across database refreshes.
npm run import # refresh title list (no enrichment)
npm run import -- --enrich 300 # + enrich 300 concepts with covers/metadata
npm run import -- --only PPSA01284 # enrich specific title IDs (comma-separated)
npm run import -- --force # accept a >5% shrink of the listTo hide the comments section for a game, add "commentsDisabled": true to its
entry in src/data/games.json. Omitting the property (or setting it to false)
keeps comments enabled.
Sources: andshrew/PlayStation-Titles (MIT, title IDs/names/regions) + the public PlayStation Store GraphQL endpoint (covers, publisher, release date, genres — hotlinked, throttled, incremental). A weekly GitHub Action refreshes the list and enriches 300 new concepts per run.
If the import fails with "persisted-query hash rejected (HTTP 400)": open a
PS5 game page on store.playstation.com with browser devtools → Network, filter
metGetConceptById, copy extensions.persistedQuery.sha256Hash from the
request, and update PSN_HASH in scripts/lib/enrich.mjs.
One markdown file per tested game in src/content/compat/<TITLEID>.md —
schema in src/lib/compat.ts, guide at /compatibility/report.
Status ladder: nothing → boots → menus → ingame → playable.
A report may use any regional title ID (e.g. PPSA10112); the site resolves
it to the game's primary entry automatically. The build fails on reports whose
title ID isn't in the database or whose filename doesn't match the front
matter.
To disable comments from an authored compatibility report, add
commentsDisabled: true to its frontmatter. Either this report setting or the
game database override hides the comments section. Automated issue conversion
preserves the manual report setting when updating an existing report.
Compatibility issues are intake records; Markdown in src/content/compat is
the published source of truth. Review the submitted build, test date, status,
ownership confirmation, notes, and evidence. When it is ready, add the
compat-approved label. The Convert compatibility report workflow then:
- Parses and sanitizes the issue form without evaluating issue content.
- Validates the title ID against
src/data/games.json. - Creates a new report or updates the existing regional report for that game.
- Runs
npm testand the full Astro build. - Opens
compat/issue-<number>as a draft PR withCloses #<number>.
The workflow never merges its PR. It can also be run manually from Actions with an issue number.
The SharpEmu organization currently prevents the built-in GITHUB_TOKEN from
creating pull requests. To activate conversion, either:
- Have an organization owner enable Allow GitHub Actions to create and approve pull requests; or
- Add a fine-grained token as the
COMPAT_BOT_TOKENActions secret, limited to this repository with read/write access to Contents, Issues, and Pull requests.
The workflow prefers COMPAT_BOT_TOKEN when present and otherwise uses
GITHUB_TOKEN, so no workflow change is needed if the organization policy is
enabled later.
/downloads renders GitHub releases from sharpemu/sharpemu at build time
(src/lib/releases.ts) — no client-side API calls, so visitors never hit
GitHub's per-IP rate limit. Freshness is push-based: publishing a release fires
notify-site.yml in the emulator repo, which sends a repository_dispatch to
this repo and redeploys within ~a minute. deploy.yml also rebuilds daily as a
safety net, and can be run by hand from the Actions tab.
Requires the SITE_DISPATCH_TOKEN secret on sharpemu/sharpemu (fine-grained
PAT scoped to this repo, Contents: read and write).
- Push this repo to GitHub (public, so giscus + issue templates work).
- Cloudflare dashboard → Workers & Pages → Create → Pages → connect the repo.
Build command
npm run build, output directorydist, Node version 22. - Custom domain: add the domain to Cloudflare (free plan). Cloudflare shows
two nameservers. In the Vercel dashboard (where the domain is registered):
Domains → your domain → Nameservers → replace with Cloudflare's pair.
Registration stays at Vercel; DNS + hosting move to Cloudflare. Then Pages
→ Custom domains → add the domain. Update
siteinastro.config.mjs.
- Repo must be public with Discussions enabled; create a "Game compatibility" discussion category (Announcements type recommended).
- Install the giscus app (github.com/apps/giscus) on the repo.
- On giscus.app, pick the repo/category, copy
repoIdandcategoryIdintoGISCUSinsrc/config.ts.
Site code is MIT (see LICENSE). Game names/metadata via andshrew (MIT). Cover art is served from the PlayStation Store and belongs to its publishers — takedown requests: open an issue. Not affiliated with Sony Interactive Entertainment.