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.js handles PokeAPI + TCG fetches, caches results in a Map, and exposes a single getPokemon(query) function.
  • app.js wires the search form, results grid, and error states.
  • deploy.yml lints, builds, and publishes to Pages on every merge to main.

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 via sr-only). Buttons announce state changes via aria-live="polite".
  • Keyboard navigation: tabindex, focus-visible styles, and skip links help keyboard-only users.
  • Color contrast + dark mode: Tailwind tokens ensure 4.5:1 contrast minimum; prefers-color-scheme toggles 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: deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run lint
- run: npm run build
- uses: actions/upload-pages-artifact@v3
with:
path: dist
deploy:
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
steps:
- 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

References