Skip to content

fix: support steam's new achievements page - #289

Open
ganey wants to merge 1 commit into
masterfrom
fix/achievements-new-page
Open

ganey wants to merge 1 commit into
masterfrom
fix/achievements-new-page

Conversation

@ganey

@ganey ganey commented Oct 29, 2026

Copy link
Copy Markdown

What

Makes the achievements enhancements work on Steam's new React achievements page (/achievements/<appid>), which has no .achieveRow, #personalAchieve or #tabs, so the old DOM scraping found nothing.

Source for the fixes

The fixes here come from #288. As an initial pass, this PR only draws on the fixes from that PR (reading Steam's embedded page data, the new URL patterns, and leaving games that Steam already groups into sets alone). It deliberately leaves out #288's UI additions (global stats toggle, state/set filters, restyled panels) so the diff stays small and existing behaviour is unchanged. Those can build on this separately.

Changes

  • Read config, schema and user unlocks from the page's valve-ssr-data instead of scraping the DOM. Names, icons and global percentages still come from GetGameAchievements, and the rendering code is unchanged.
  • Sort by time uses the unlock timestamps from that data. This drops the Finnish-locale refetch and date parsing.
  • Wait for Steam's page to finish booting before inserting our list, and find the list again if React re-renders it, because inserting too early causes a React hydration error (#418).
  • Hide Steam's own filter bar, since it only controls the list we hide.
  • Use the real header image from the store item data (newer apps use hashed asset paths) and a title regex for the new <title> format.
  • Reset heading margins and style the sort button, because the new page has no CSS reset and the old button classes don't exist.
  • Manifest: add /id|profiles/*/achievements/* and /achievements/*.
  • Games where Steam already has native sets (for example L4D2, Portal 2) are skipped.

Not supported

  • Compare view is not supported on the new page. The isCompareView branches are still in the code, now fixed to false, to keep this diff small.
  • Locked-achievement progress bars (for example 5/10) are not shown, because they came from scraping.
  • Sort by time still works once per page load, as before.

Testing

  • npm test (eslint, stylelint, prettier, tsc) and web-ext lint pass.
  • Chrome, unpacked: personal page with real unlocks (dates, sort by time), another user's profile, logged-out global page, Payday 2 (1342 achievements), L4D2 and Portal 2 (skipped), and the legacy /stats/... URLs, which redirect to the new URL.
  • Firefox 155 (desktop) and Firefox 159 on an Android emulator: personal and global pages and sort by time.
  • Group updates (GetAchievementsGroups) worked in Firefox (Terraria split into 5 groups, Payday 2 into 123). It is blocked for unpacked Chrome builds because the extension ID differs, so it wasn't tested there.
  • Not tested: compare view, and logged-in global page (Steam redirects owners to the personal page).

Known rough edge: the wait for Steam's page uses a fixed 1.5s delay (marked with a shortcut: comment), because there is no signal for when hydration finishes.

🤖 Generated with Claude Code

Steam moved achievements to a React page at /achievements/<appid> with no
.achieveRow, #personalAchieve or #tabs, so the old DOM scraping found nothing.

Read the data from the page's valve-ssr-data (config, schema, unlocks) instead
of scraping, and keep the existing rendering. Sorting by time now uses the
unlock timestamps from that data instead of re-fetching the page in Finnish.
Games that Steam already groups into sets are left alone.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants