Developing an Interactive Pokédex: API Integration and Responsive Design
Context: Personal side project hosted on GitHub Pages. No auth, no production users—just a learning sandbox for API integration and accessibility.
AI assist: ChatGPT/Copilot generated some UI skeletons and fetch helpers. Every AI-assisted file is noted in the repo.
Status: Live demo works today; offline mode, tests, and Gen 2+ support remain future work.
Reality snapshot
- Two API sources: PokeAPI (stats/types/sprites) and Pokémon TCG API (card art).
- Stack: Vanilla JS + Tailwind CSS + small helper modules.
- Hosting: GitHub Pages with GitHub Actions handling lint/build/deploy.
- Limitations: Only Gen 1 (151 Pokémon), no service worker, rate limits show “please try again” warnings during heavy testing.
Architecture & data flow
interactive-pokedex/├── src/│ ├── app.js│ ├── api.js│ ├── ui/│ └── utils/├── public/│ └── index.html└── .github/workflows/deploy.yml
api.jshandles PokeAPI + TCG fetches, caches results in aMap, and exposes a singlegetPokemon(query)function.app.jswires the search form, results grid, and error states.deploy.ymllints, builds, and publishes to Pages on every merge tomain.
Accessibility & UX decisions
- Semantic HTML:
main,section,article, etc. Each card has a descriptive heading + region label. - Forms: search input has a
<label>(visually hidden viasr-only). Buttons announce state changes viaaria-live="polite". - Keyboard navigation:
tabindex,focus-visiblestyles, and skip links help keyboard-only users. - Color contrast + dark mode: Tailwind tokens ensure 4.5:1 contrast minimum;
prefers-color-schemetoggles styles automatically. - Error messaging: rate-limit or network failures show inline notices + instructions to retry.
Performance considerations
- Warm-cache searches respond in under one second on my laptop; throttled 3G loads around two seconds (Chrome DevTools numbers).
- Simple caching layer (Map + sessionStorage) avoids duplicate API calls.
- Images lazy-load via
loading="lazy"; sprites have width/height attributes to prevent layout shifts. - Lighthouse scores ~98–100 for accessibility/performance locally; I log scores in the repo issues backlog.
Deployment workflow
name: deployon:push:branches: [main]jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: actions/setup-node@v4with:node-version: 20- run: npm ci- run: npm run lint- run: npm run build- uses: actions/upload-pages-artifact@v3with:path: distdeploy:needs: buildruns-on: ubuntu-latestpermissions:pages: writeid-token: writesteps:- uses: actions/deploy-pages@v4
- Keeps build artifacts immutable. Failures in lint/tests stop the deploy before it hits Pages.
What’s next
- Add Service Worker caching so Gen 1 data works offline.
- Expand beyond Gen 1 with pagination + infinite scroll (needs better caching + UI).
- Write Jest tests for fetch logic and use Playwright for end-to-end flows.
- Document rate-limit handling clearly on the site (currently only in README).
Repro steps and smoke test
npm install && npm run devto run locally.- Hit search for “pikachu” and “charizard”; confirm stats + TCG art load and errors are absent.
- Toggle dark mode (prefers-color-scheme) to ensure contrast holds.
- Throttle network in DevTools to “Slow 3G” and verify skeletons + aria-live messages appear.
- Run
npm run lint && npm run buildbefore pushing; Pages deploys on main only.
Bugs I already hit
- Rate limits: PokeAPI returned 429s; added backoff + user messaging instead of silent failures.
- Layout shifts: Missing width/height on sprites caused jank. Fixed with explicit dimensions and lazy loading.
- Keyboard traps: Early modal/search focus traps were missing; added focus management + escape handlers.
- Caching lies: sessionStorage served stale data after deploys. Added a
versionkey to bust caches on build.
Interview angles
- Why plain JS: Wanted to show fundamentals without a framework crutch; also keeps bundle tiny for Pages.
- Accessibility discipline: Lighthouse + manual keyboard checks every deploy; aria-live for status messages.
- Honesty: No auth, no monetization, no Gen 2+. I state that up front.
- Testing plan: Unit tests for fetch/caching; Playwright for search, detail, and error flows.
Stretch ideas
- Add a “compare two Pokémon” view with charted stats.
- Ship an offline-first mode with a service worker + IndexedDB cache.
- Surface API status badges so users know if PokeAPI/TCG is throttling.
- Publish a short Loom walkthrough for non-technical viewers (kids, parents) to enjoy the site.
Links
- Live demo: https://bradleymatera.github.io/Interactive-Pokedex/
- Repo: https://github.com/BradleyMatera/Interactive-Pokedex
- Prompt log + runbooks: see
/docs/inside the repo