Skip to content

feat(games): add the games landing and five paged IGDB list pages - #57

Merged
kris1027 merged 25 commits into
mainfrom
feat/games-home-list-pages
Oct 25, 2026
Merged

kris1027 merged 25 commits into
mainfrom
feat/games-home-list-pages

Conversation

@kris1027

Copy link
Copy Markdown
Owner

What

/games is now the games landing. It uses the same parallax landing as /shows and /movies, filled with five IGDB lists: Trending, Popular, Recently released, Coming soon and Top rated. Each list also gets its own paged See all page under /games/{slug}. The GAMES tab now shows on every page while NEXT_PUBLIC_GAMES_LIBRARY is on.

Why

Implements spec 0028, scope feature G6 in docs/scope/games.md. It gives visitors a way to find a game without searching, and it delivers the navigation pieces spec 0027 left for G6. The landing sections now draw a game the same way they draw a show or a movie, so there is still one landing, not a copy.

Changes

IGDB module (lib/igdb/)

  • New getPopularGames("trending" | "popular"). It reads IGDB popularity_primitives (types Visits = 1 and Playing = 3, pinned in constants.ts), batch reads up to 500 ids, drops hidden or missing games, and keeps the rank order. Both requests sit in one cached scope with an hours lifetime, so a partial result is never cached as a success.
  • discoverGames accepts pageSize of 20 or 24 (default 20, so existing callers don't change). It is validated before the cache and is part of the cache key. readSummaryPage computes its offset from the page size, so pages never overlap.
  • GameSummary.artUrl: the artwork, or else a screenshot, with the lowest image_id, at t_1080p. IGDB_SUMMARY_FIELDS now also asks for artworks and screenshots.
  • lib/images/igdb-loader.ts steps art URLs down a separate IGDB_ART_LADDER, the same way it steps covers.
  • pnpm igdb:live now checks the art rung widths, the two popularity type ids and names, both popularity lists, and that the Recently released window holds at least 12 hyped games.

Lists and routes

  • The list registry (lib/catalog/lists.ts) gains five game lists. catalogListsFor's MediaType overload never returns them, so the sitemap stays free of /games URLs.
  • lib/catalog/game-lists.ts builds the discover options from the UTC day (60 day Recently released window, 120 day Coming soon window, 100 rating floor for Top rated).
  • lib/catalog-list-read.ts gains a game branch. Popularity lists are sliced into pages of 24 with an exact count. Discover lists use IGDB's count, or Next only, when no count comes back.
  • Five route folders under app/games/ copy the movie list page pattern. CATALOG_PATHS.game is /games, and MediaType stays "tv" | "movie".
  • proxy.ts lets exactly the five slugs through before parseGameId. /games/Trending, /games/coming_soon and /games/trending.jpg still get a real 404.

Landing

  • LandingItem carries mediaType: LibraryType and a rating: { source, value } in place of tmdbRating. The badge picks the TMDB or IGDB rating badge from the source.
  • app/games/page.tsx renders CatalogLanding with the game slots. The hero shows the first Trending game over its art, IGDB genres (left out if that read fails), and GameTrackingSlot in its own Suspense boundary. There is no Trailer button.
  • The wide card now has its own view (wide-card.tsx), apart from the session slots. Coming soon cards show the UTC release day.
  • Game cards have no personal status badge and no controls yet (G8 adds them).

Navigation

  • With the flag on, GAMES shows on every page. It is lit on /games*, links to /games from the catalog, title and search pages, and switches ?type=game in place on the library pages.
  • The navbar search is hidden on /games*. The check uses usePathname only, so the shells stay prerendered.
  • The logo remembers game, but it follows that memory only while the flag is on.
  • Empty games library tabs and the game not found panel now offer Browse games, linking to /games.

SEO: every games page is noindex, with no canonical and no share card fields of its own. app/sitemap.test.ts asserts there is no /games URL in the sitemap.

Showcase: a "Games landing and lists" section with a game card, wide cards with and without art, a failed section, and the list page error and empty panels.

How to test / verify

These steps follow the recorded verify run, where every step was ticked. Run with NEXT_PUBLIC_GAMES_LIBRARY=on unless a step says otherwise.

  • You can run pnpm typecheck && pnpm lint:ci && pnpm test. All three should pass.
  • You can run IGDB_CLIENT_ID= IGDB_CLIENT_SECRET= pnpm build. It should pass and list /games and the five list pages as partially prerendered (◐).
  • You can run pnpm igdb:live (needs IGDB credentials). It should report Visits = 1, Playing = 3, the art rungs, and at least 12 hyped recent releases.
  • Open /games at 1280px. You should see the hero, then Trending now, Popular, Recently released (sidebar New releases), Coming soon and Top rated, each with See all.
  • Open a See all page. You should see ← Games, the h1, the note, 24 cards and Page 1 of M. /games/trending?page=99 should show the "no such page" panel.
  • Try curl -s -o /dev/null -w '%{http_code}' localhost:3000/games/Trending. It should print 404. /games/coming-soon and /games/1942 should print 200.
  • Signed in (pnpm dev:docker), the hero should offer Want to play / Playing / Finished, with the release gate on an unreleased game. Signed out, it should show no status control.
  • Set a bad IGDB_CLIENT_SECRET and restart. Each landing section should show its own Try again, and a list page should show Couldn't reach IGDB with a retry link.
  • Set the flag to off and restart. No GAMES tab should show, and /games should still load by URL.
  • At 375px there should be no horizontal scroll, and with reduced motion on, nothing should move.

Risk & rollout

No migration, no schema change, and no new environment variables. Production leaves NEXT_PUBLIC_GAMES_LIBRARY unset, so no GAMES tab shows there. But /games and its list pages do answer by URL in production (that's by design, AC-14). They stay noindex and out of the sitemap until G10.

What can break: the shared landing components and list page now branch on three media types, so /shows and /movies are in the blast radius. Their existing tests still pass, but you may want to look at them in a browser. Every summary read now carries two more expanded fields (artworks, screenshots), so batch and discover payloads grow. A popularity list is one batch of 500 ids, the heaviest single IGDB read in the app, cached for hours.

The popularity type ids are IGDB facts that could change. pnpm igdb:live is the only guard.

Rollback is a plain revert. There is no stored state to undo.

Notes for reviewers

  • /check review has not been run for spec 0028 yet (there's no file in docs/reviews/ for it). You may want to run it before merge.
  • MediaType is deliberately not widened. game travels as LibraryType, so /search and the TMDB reads still can't receive it until G7. The proxy's local CATALOG_PATHS is a different constant from the one in lib/catalog/media-type.ts.
  • Coming soon's landing rows skip items 21 to 24 of page 1 (they still show on See all), because each page of 24 fills only its own rows. The spec accepts this tradeoff.
  • Trending and Popular may share games. That matches the TMDB landings.
  • Spec 0025 (AC-7, the not found button) and spec 0027 (AC-4 logo, AC-14 Browse games) still need their amendment notes. That's a follow-up in the spec, together with the lib/igdb/AGENTS.md update in /sync.

🤖 Generated with Claude Code

kris1027 and others added 14 commits October 25, 2026 17:18
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g sections games

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o /games

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he session slots

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kris1027 kris1027 added feature New user-facing functionality ui Layouts, styling, and shared interface components labels Oct 25, 2026
@kris1027 kris1027 self-assigned this Oct 25, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in BeStats Oct 25, 2026
@vercel

vercel Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
bestats Ready Ready Preview Oct 25, 2026 5:36pm UTC

kris1027 and others added 8 commits October 25, 2026 18:16
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The list page's error and empty panels move to list-panels.tsx so /showcase
renders the real ones instead of copying their text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kris1027 and others added 3 commits October 25, 2026 18:22
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kris1027
kris1027 merged commit 5de0608 into main Oct 25, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in BeStats Oct 25, 2026
@kris1027
kris1027 deleted the feat/games-home-list-pages branch October 25, 2026 17:38

This branch was successfully deployed

1 active deployment
Preview — 130392c6 Deployed Oct 25, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New user-facing functionality ui Layouts, styling, and shared interface components

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant