Skip to main content
Open Tarteel is built as a Progressive Web App (PWA), providing a native app-like experience directly from your browser with offline capabilities, installability, and background playback.

Installing Open Tarteel

Install Open Tarteel on any device for quick access:

Chrome/Edge/Brave

  1. Visit Open Tarteel in your browser
  2. Look for the install icon in the address bar
  3. Click “Install Open Tarteel”
  4. The app launches in its own window

Firefox

Firefox doesn’t support PWA installation, but you can:
  • Add a bookmark for quick access
  • Use fullscreen mode for app-like experience

PWA Manifest

The app manifest defines how Open Tarteel appears when installed:
// From manifest.ts:3-13
export default function manifest(): MetadataRoute.Manifest {
  return {
    id: '9a008c3173fcca3c4def71adedd5bd3f',
    theme_color: '#000000',
    background_color: '#000000',
    display: 'standalone',
    scope: '/',
    start_url: '/',
    name: 'Open Tarteel',
    short_name: 'Open Tarteel',
    description: 'Quran streaming application',
  };
}

Manifest Features

Standalone Display

Opens in its own window without browser UI

Theme Color

Black theme color for status bar integration

App Icons

192x192 and 512x512 icons for all devices

Screenshots

Desktop and mobile screenshots for app stores

Offline Support

Open Tarteel works offline thanks to service worker caching:

Audio Caching

Quran recitations are cached for offline playback:
// From sw.ts:23-44
const quranAudioCache = {
  matcher: ({ url }: { url: URL }) => {
    return (
      url.hostname.endsWith('.mp3quran.net') &&
      /^server\d+$/.test(url.hostname.split('.')[0]) &&
      /^\d+\.mp3$/.test(url.pathname.slice(1))
    );
  },
  handler: new CacheFirst({
    cacheName: 'quran-audio',
    plugins: [
      new ExpirationPlugin({
        maxEntries: 20,
        maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
      }),
      new CacheableResponsePlugin({
        statuses: [200],
      }),
    ],
  }),
};

Cache Strategy

How it works:
  1. Request audio file
  2. Check if cached
  3. Return from cache if available (instant playback)
  4. Otherwise fetch from network
  5. Cache the response for future use
Benefits:
  • Instant playback of cached Surahs
  • Works completely offline
  • Reduces bandwidth usage
  • Faster performance

Cache Limits

The audio cache stores up to 20 Surah files for 7 days. Older or excess files are automatically removed to manage storage.

Service Worker

The service worker enables offline functionality:
// From sw.ts:49-57
const serwist = new Serwist({
  precacheEntries: self.__SW_MANIFEST,
  skipWaiting: true,
  clientsClaim: true,
  navigationPreload: true,
  runtimeCaching,
});

serwist.addEventListeners();

Service Worker Features

Core app files are precached:
  • HTML pages
  • CSS stylesheets
  • JavaScript bundles
  • App icons and assets
These load instantly on repeat visits.

Update Notifications

When a new version is available:
// From pwa-updater.tsx:10-21
useEffect(() => {
  if (typeof window === 'undefined' || !('wb' in window)) {
    return;
  }

  window.wb.addEventListener('controlling', () => {
    globalThis.location.reload();
  });

  window.wb.addEventListener('waiting', () => setIsOpen(true));
  window.wb.register();
}, []);

Update Flow

  1. Detection - New service worker detects update
  2. Waiting - Update waits in background
  3. Notification - User sees update dialog
  4. Activation - User clicks “Reload and update”
  5. Refresh - Page reloads with new version
Users can choose when to update. The app continues working with the old version until they’re ready to reload.

App Shortcuts

Installed PWA includes app shortcuts:
// From manifest.ts:72-97
shortcuts: [
  {
    name: 'Contact us',
    url: '/contact',
    description: 'Contact us page',
    icons: [{
      src: 'images/shortcuts/contact.png',
      sizes: '96x96',
      type: 'image/png',
    }],
  },
  {
    name: 'About us',
    url: '/about',
    description: 'About us page',
    icons: [{
      src: 'images/shortcuts/about.png',
      sizes: '96x96',
      type: 'image/png',
    }],
  },
]
Right-click the app icon (or long-press on mobile) to access shortcuts for quick navigation.

Media Session API

Background playback controls integrate with system media controls:
// From use-media-session.ts:31-56
useEffect(() => {
  if (!('mediaSession' in navigator)) return;

  const track = playlist[currentTrackId];
  if (!track || !selectedReciter) return;
  
  navigator.mediaSession.metadata = new MediaMetadata({
    title: `${track.surahId} - ${surahName}`,
    artist: selectedReciter.name,
    album: selectedReciter.moshaf.name,
    artwork: [{
      src: '/images/512x512.png',
      sizes: '512x512',
      type: 'image/png',
    }],
  });

  navigator.mediaSession.setActionHandler('play', onPlay);
  navigator.mediaSession.setActionHandler('pause', onPause);
  navigator.mediaSession.setActionHandler('previoustrack', onPrev);
  navigator.mediaSession.setActionHandler('nexttrack', onNext);
}, [/* deps */]);

Media Controls

Lock Screen

Control playback from your lock screen

Notification

Media controls in notification shade

Bluetooth

Car and headphone button support

Keyboard

Media keys on keyboard work
iOS Safari has limited Media Session API support. Controls may not work as expected on iOS devices.

Display Modes

The PWA supports different display modes:
Default mode - app runs in its own window without browser UI. Looks and feels like a native app.

Launch Handling

The app handles launches efficiently:
// From manifest.ts:18-20
launch_handler: {
  client_mode: 'auto',
}
  • Auto Mode - Opens in existing window if already running
  • Single Instance - Prevents multiple app windows
  • State Preservation - Maintains playback state when reopened
The PWA can handle web links:
// From manifest.ts:21-26
handle_links: [
  {
    url: 'https://tarteel.quran.us.kg',
    action: 'navigate',
  },
]
Clicking Open Tarteel links opens them in the installed app rather than the browser.

Storage Management

The PWA uses browser storage efficiently:

Storage Types

Cache Storage

Service worker caches for offline files

LocalStorage

User preferences and favorites

IndexedDB

GunDB distributed database

Session Storage

Temporary session data

Storage Limits

  • Audio Cache: 20 files maximum, 7-day expiration
  • LocalStorage: ~5-10MB depending on browser
  • Total Cache: Managed by browser’s storage quota
Browsers may clear PWA storage if device storage is low. Cache your most-listened Surahs by playing them.

Platform-Specific Features

Android

  • Add to home screen
  • Splash screen on launch
  • System share integration
  • Background playback
  • Media notification controls

iOS

  • Add to home screen (Safari only)
  • Limited background playback
  • No push notifications
  • No background sync

Desktop

  • Window installation
  • System tray integration (Chromium)
  • Keyboard shortcuts
  • File system access (future)
The experience is best on Android and Desktop Chrome/Edge due to full PWA support.

Checking PWA Status

Verify PWA features are working:
  1. Open DevTools (F12)
  2. Go to Application tab
  3. Check:
    • Service Worker is registered and active
    • Cache Storage has entries
    • Manifest is valid
    • Installability criteria met

Benefits of PWA

  • No App Store - Install directly from browser
  • Small Size - No large download, uses browser engine
  • Always Updated - Auto-updates in background
  • Cross-Platform - Works on all devices
  • Offline First - Works without internet
  • Fast - Cached resources load instantly
  • Linkable - Can be shared via URL
  • Secure - HTTPS required, built-in security

Build docs developers (and LLMs) love