Enhanced Game View — brings the Steam store page onto your library game-detail page.
A Decky Loader plugin for SteamOS / Steam Deck that brings the content normally shown on a game's store page — trailers, screenshots, description, features, reviews, Steam Deck compatibility and update history — onto the game's library details page, rendered below the header so it never covers or blocks the Play button.
Injected into the scrollable content area beneath the hero/Play button:
| Section | Source | Contents |
|---|---|---|
| Header row | store + deck | Review summary + Steam Deck compatibility badge |
| Media | appdetails |
Trailer thumbnails (tap to play) + screenshots (tap to zoom) |
| About this game | appdetails |
Full description (sanitized HTML), expandable |
| Features & details | appdetails |
Genres/categories, developer, publisher, release date, platforms, controller support, Metacritic, price, languages |
| Steam Deck compatibility | deck report | Verified/Playable/Unsupported + reviewer notes |
| Reviews | appreviews |
Score summary, positive %, recent review cards |
| Update history | ISteamNews |
Recent patch notes / announcements (tap to read) |
Everything is gamepad-navigable and each section is collapsible. Section visibility and cache clearing are controlled from the plugin's Quick Access panel.
- Frontend (
src/, TypeScript/React via@decky/api+@decky/ui): patches the/library/app/:appidroute withrouterHook.addPatch, walks the Steam React tree (afterPatch→wrapReactType→findInReactTreeonappDetailsClasses.InnerContainer) and splices<StorePanel/>in just below the header. Every hop is guarded so a Steam client update degrades to "no panel" rather than crashing the page. - Backend (
main.py, Python stdlib only): fetches from Steam's store/web APIs (bypassing the browser's CORS restrictions), normalizes and sanitizes the JSON, converts news BBCODE → safe HTML, and caches responses to disk (DECKY_PLUGIN_RUNTIME_DIR) with per-kind TTLs plus negative caching and in-flight de-duplication to stay well under Steam's rate limits.
Data sources (no API key required):
store.steampowered.com/api/appdetails, store.steampowered.com/appreviews,
api.steampowered.com/ISteamNews/GetNewsForApp, and the store Deck
compatibility report endpoint.
Requires Node 18+ and Python 3. pnpm is recommended (it's what Decky uses), but
npm works too.
# with pnpm (recommended)
pnpm install
pnpm build
# or with npm
npm install
npm run buildThis produces dist/index.js. The main.py, plugin.json and package.json
ship as-is.
You need Decky Loader installed, and Decky Developer mode enabled for the zip/dev flow.
Copy this whole folder (after building, so dist/ exists) to the Deck at:
~/homebrew/plugins/EnhancedGV/
so that it contains at least: plugin.json, main.py, dist/index.js,
package.json. Then restart Steam / reload Decky. Example from a PC:
scp -r "steam-store-panel" deck@<deck-ip>:"/home/deck/homebrew/plugins/EnhancedGV"Build first, then create a zip whose single top-level folder holds the plugin
files (dist/, main.py, plugin.json, package.json, LICENSE, README.md).
PowerShell (Windows):
Compress-Archive -Path plugin.json,main.py,package.json,dist,LICENSE,README.md `
-DestinationPath ..\SteamStorePanel.zipbash (Deck/Linux/macOS):
zip -r ../SteamStorePanel.zip plugin.json main.py package.json dist LICENSE README.mdThen in the Decky menu: Settings → Developer → enable Developer mode, then Install Plugin from ZIP and pick the file. Open any game in your library — the store panel appears below the Play button.
Everything is controlled from the Quick Access menu → EnhancedGV panel. Open a game first so the game-specific options appear.
After installing
- Sections shown on the game page — turn Media, About, Features & details, Steam Deck, Reviews, and Update history on or off.
- Expanded by default — choose which sections start open vs. collapsed.
- Store language follows your Steam client language automatically; the Status
row shows what it detected. To force one, set
languagein the plugin's settings to a Steam language name (e.g.french). - Clear cached store data forces a fresh fetch if anything looks stale.
Matching non-Steam games
Non-Steam games (emulator shortcuts, Epic/GOG titles added to Steam, etc.) have no Steam store page of their own, so EnhancedGV finds one for you. The first time you open one, it searches the Steam store by the game's title and uses the best match — no action needed — and remembers it so it only happens once.
To check or fix a match, open Quick Access → EnhancedGV → Store data source while viewing the game:
- The Steam App ID field shows which store page the content comes from, and
the
Title (Year)below it lets you confirm it's the right game. - Wrong match? Type the correct App ID, or paste the game's
store.steampowered.com/app/…URL, and press Save ID. Your choice is sticky and never gets overwritten automatically. - Clear (leave blank) removes the match and keeps the game unmatched — use it to hide the store panel for a game you don't want it on.
- Re-detect automatically discards the current match and runs the title search again.
This works for regular Steam games too — you'll rarely need it, but you can point any game at a different store page the same way.
- Steam client fragility (test on-device). The injection depends on Steam's
closed-source UI tree, which changes between client updates. The patch uses
feature-based lookups (
appDetailsClasses.InnerContainer, the AppOverview node) and bails out safely if the tree shape changes — but if a future Steam update stops the panel appearing, the tree-navigation insrc/patchLibraryApp.tsxis the place to adjust (the same technique used by ProtonDB Badges / HLTB for Deck). - Trailers are best-effort. Steam's
appdetailsno longer returns progressivemp4/webmURLs — only adaptivedash/hlsmanifests. The backend derives candidate.mp4/.webmURLs from the thumbnail path and the video modal tries them in order; if none play in the embedded browser, the poster remains. Screenshots are always reliable. - Non-Steam games are matched to a Steam store page by title automatically, and you can correct or clear the match from the QAM (see Setup & tips). Games with no Steam counterpart stay cleanly "not identified".
- Rate limits. The store endpoints are unofficial and throttle ~200 req / 5 min per IP; the disk cache + de-dup keep normal usage far below that.
- Privacy. Requests go directly from your device to Steam's public APIs for the appid you're viewing. No API key, no third-party servers.
The store content is injected into Steam's app-details page, whose internal React tree is closed-source and shifts between client builds. If nothing shows up:
- Open Quick Access menu → EnhancedGV → Diagnostics (last game page) after
viewing a game. It reports, for the last game page rendered:
- InnerContainer class — should be a hashed class name, not
MISSING. - Found renderFunc / Found game (appid) / Container matched / Panel injected.
- Note and, on failure, the list of container class names actually present.
- InnerContainer class — should be a hashed class name, not
- The first
no/MISSING/nonerow pinpoints the hop that failed:Found renderFunc = NO→ the route wrapper changed.Found game (appid) = NO→ the overview node moved.Container matched = none→ the scroll-container class changed; the "Container classes seen" line lists the real ones to target.
- The Decky console log mirrors this with
[EnhancedGV]lines.
Layout can be switched between stacked sections (default, most reliable) and a tab strip under Quick Access → EnhancedGV → Layout → Show as tabs.
steam-store-panel/
├── plugin.json # Decky manifest
├── package.json # deps + build scripts
├── rollup.config.js # re-exports @decky/rollup
├── tsconfig.json
├── main.py # Python backend: fetch + normalize + cache
├── decky.pyi # type stub for `import decky` (editor only)
├── dist/index.js # built frontend bundle (after `npm run build`)
└── src/
├── index.tsx # definePlugin: registers patch + QAM panel
├── patchLibraryApp.tsx # the /library/app/:appid injection
├── api.ts # callable() bindings to main.py
├── types.ts # shared TS types
├── hooks/useAppData.ts # fetch-on-mount + module cache
└── components/ # StorePanel + section components
BSD-3-Clause. Not affiliated with Valve. "Steam" and "Steam Deck" are trademarks of Valve Corporation.



