Web Uygulamanızı Telefona Yükleyin: React PWA Rehberi

Depocular cihazlarına web tabanlı ERP uygulamasını nasıl yükler? App Store redlerini beklemeden React PWA (Service Worker + Manifest) ile %100 Native...

İş Problemi: “Bu Web Sitesi Depoda Nasıl Kullanılacak?!”

AstaFlow gibi B2B kurumsal yazılımları geliştirip firmaya teslim edersiniz. “Sistemi kullanıma açtık” dersiniz. Sonra lojistikteki depo personeli veya sahada gezen plasiyer (satışçı) telefonun Chrome tarayıcısını açar, uzun bir link yazar https://app.astaflow.com. Giriş yapar, fakat ekranda dev gibi bir Chrome adres çubuğu, altta gezinme sekmeleri kalmıştır. Karekod okutucu (Camera API) çalışırken sayfa kayıp durur. Ekip isyan eder: “Bizim uygulama yapmamız lazımdı, bu web sitesi!”

Eğer bu ihtiyacı gidermek için React Native veya Swift yazıp App Store’a göndermeye kalkarsanız aylarca beklersiniz. Zaten “Sadece şirket personeli kullanacak” olan bir uygulamayı Apple genellikle “Private B2B App” diyerek reject (red) eder.

Çözüm: Uygulamalarınızı PWA (Progressive Web Application) Yapını! Service workerlar yardımıyla bir React sitesinin telefon hafızasına statik olarak yerleştiği muhteşem mimari.

PWA ile Kullanıcı Ne Yaşar (Mental Çıktı)

Sıradan bir web sitesi ile profesyonel PWA arasındaki farklar uçurumdur:

Deneyim NoktasıDüz Web SayfasıPWA React App
ErişilebilirlikTarayıcıya link girmek şarttırTelefon Ana Ekranında şirket logolu İkon!
Ara YüzTepede Adres Çubuğu, Altta Safari barları%100 Tam Ekran (Standalone mode)
İnternet Kesintisi”Dinazor Oyunu” ÇıkarMükemmel CSS’e sahip Offline Ekran Gelir
Yükleme (Boot) SüresiHer resim tekrar yüklenirResimler App gibi cihazda yüklüdür, anında açılır

Adım Adım Entegrasyon (React PWA Kod Mimarisi)

PWA bir dil değil, web evreninin 2 dosyasının public klasörüne eklenmesi sanatıdır.

Aşama 1: manifest.json (Kurulum Beyanı)

React (Vite veya Next.js) projenizin root public klasörüne bu JSON’ı koyarsınız. Tarayıcı uygulamaya girdiğinde “Aaa bu indirilebilir formattaymış!” der.

{
  "name": "AstaFlow Pro İş Yönetimi",
  "short_name": "AstaFlow",
  "description": "Stok ve Karar Destek Terminali",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#1e293b",
  "icons": [
    {
      "src": "/pwa-icons/icon-192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/pwa-icons/icon-512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ]
}

Püf Nokta: display: "standalone", PWA’nın kalbidir. Bunu yazmazsanız sadece link kaydetmiş (Shortcut) olursunuz, tepedeki iğrenç web çubuğu kalkmaz!

Aşama 2: Service Worker (SW.js) - Arkadaki Motor

Sistemde internet koptuğunda “Dinozor” çıkmamasını sağlayan, varlıkları tarayıcı diskine kaydeden aracı işçidir. (Vite kullanıyorsanız vite-plugin-pwa hayat kurtarır). Standart bir public/sw.js dosyası:

const CACHE_VERSION = 'astaflow-cache-v1';

// Uygulama yüklenirken temel dosyaları (Offline Kabuk - AppShell) sakla
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_VERSION).then((cache) => {
      return cache.addAll(['/']); 
      // Vite kullanıyorsanız offline.html ve chunkları otomatik inject eder.
    })
  );
});

// İnternet varlıkları ile Telefon Cache arasına ajan yerleştir
self.addEventListener('fetch', (event) => {
  // Veritabanı API isteklerini (Supabase, MSSQL) asla Cache'leme!
  if (event.request.url.includes('/api/') || event.request.url.includes('supabase.co')) {
    return;
  }

  event.respondWith(
    caches.match(event.request).then((cachedResponse) => {
      // Diskinde varsa (Resim, Font, CSS) İNTERNETİ beklemeden anında yükle!
      if (cachedResponse) {
        return cachedResponse;
      }
      return fetch(event.request);
    })
  );
});

Aşama 3: HTML Linkleri ve PWA Çağrısı

index.html dosyanıza şu meta başlıklarını kesinlikle koymalısınız (Özellikle gıcık Apple donanımlarını ehlileştirmek için):

<link rel="manifest" href="/manifest.json">
<!-- Apple Özellikleri (Apple manifesti bazen okumaz) -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="apple-touch-icon" href="/pwa-icons/icon-192.png">

Edge Cases (Ölümcül Riskler) ve Dağıtım

  1. iOS “Add to Homescreen” Eziyeti: Android (Chrome) telefonlar uygulamanıza girince otomatik olarak altta muazzam bir “Uygulamayı Ana Ekrana Ekle” pop-up’ı çıkartırlar. Ancak Apple (Safari IOS), Steve Jobs inatçılığıyla bu API’yi otomatik göstermez. Kullanıcıların el ile Safari’den “Paylaş İkonu” -> “Ana Ekrana Ekle” yapması gerekir. Projelerde ekrana bir tooltip çizip “Yüklemek için Paylaş ikonuna basın” diye UX bileşeni koymak zorundasınız!
  2. Hard-Refresh İmkansızlığı: Uygulama telefonda Standalone olarak kurulduğunda kullanıcı, ekranda bir şey takılırsa Tarayıcıdaki Yenile (F5/Refresh) tuşunu bulamaz! Her şey App gibi olduğu için yenile tuşu yoktur. Uygulama içine bir swipe-down (Aşağı çekince yenile) modülü eklemek şarttır.
  3. Versiyon Güncellemesi Sorunu (Service Worker Sıkışması): Siz sisteme yeni bir ekleme yaptınız, ancak telefonda sw.js o siteyi RAM’e cache’lediği için sistem hep eski faturayı basacaktır. Kullanıcıya “Yeni versiyon var, tıklayın ve uygulamayı tazeleyin” çıkartısını veren kodları (örn NeedRefreshDialog komponentlerini) mutlaka kurgunuza koymalısınız. Yoksa depoculardaki telefonlardan eski kodları silemezsiniz.

Bu Bilgiyi Nereden Biliyoruz? (Kaynaklar)

📚 İlgili Yazılar