Skip to main content

Challenge — PWA Recipe App

Objective

Build a Progressive Web App for saving and browsing recipes. It must be installable, work offline, and score 90+ on Lighthouse.

Requirements

PWA Features (40 points)

  • Web app manifest with correct icons (192px, 512px, maskable)
  • Service worker registered via vite-plugin-pwa
  • App is installable (passes Chrome's criteria)
  • Offline fallback page when no cache is available
  • Previously viewed recipes accessible offline
  • Update prompt when a new version is deployed

App Features (40 points)

  • Browse recipes from TheMealDB API (free, no key needed)
  • Search recipes by name
  • View recipe detail (ingredients, instructions, YouTube video link)
  • Save recipes to favorites (stored in localStorage)
  • Offline: favorites page works without internet

Performance (20 points)

Lighthouse audit (in production build, npm run preview):

  • Performance: ≥ 90
  • Accessibility: ≥ 95
  • Best Practices: ≥ 90
  • SEO: ≥ 90
  • PWA: all checks green

Caching Strategy

// vite.config.ts
workbox: {
runtimeCaching: [
{
// Cache API responses — network first, 1 hour TTL
urlPattern: /^https:\/\/www\.themealdb\.com\//,
handler: 'NetworkFirst',
options: {
cacheName: 'mealdb-api',
expiration: { maxEntries: 100, maxAgeSeconds: 3600 },
},
},
{
// Cache meal images — cache first, 7 days
urlPattern: /^https:\/\/www\.themealdb\.com\/images\//,
handler: 'CacheFirst',
options: {
cacheName: 'mealdb-images',
expiration: { maxEntries: 50, maxAgeSeconds: 7 * 24 * 3600 },
},
},
],
}

Grading

CriteriaPoints
Manifest with icons10
Service worker registered10
App installable10
Offline page5
Offline access to cached recipes5
Recipe list and search15
Recipe detail page10
Favorites with localStorage15
Lighthouse Performance ≥ 9010
Lighthouse PWA all green10
Total100

Bonus

  • Push notification when a new recipe category is added (mock the server side)
  • Background sync: save a recipe while offline, sync to server when reconnected
  • Share recipe via Web Share API: navigator.share({ title, url })
  • Add to home screen custom prompt with install statistics tracking