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).
Links
- Live demo: https://bradleymatera.github.io/Interactive-Pokedex/
- Repo: https://github.com/BradleyMatera/Interactive-Pokedex
- Prompt log + runbooks: see
/docs/inside the repo