LivaDocsv1.1.2

LivaPwaInstall

Web uygulamasını ana ekrana kurmayı teklif eden banner ve tarayıcının kurulum yeteneğini tek bir duruma indiren useLivaPwaInstall hook'u. Chromium tabanlı tarayıcılarda (Android Chrome, Edge, masaüstü Chrome) "Yükle" butonu tarayıcının yerel kurulum diyaloğunu açar. iOS'ta böyle bir diyalog olmadığı için Paylaş menüsü adımlarını anlatan bir pencere gösterilir. Uygulama ana ekrandan (standalone) açıldıysa bileşen hiçbir şey çizmez.

import { LivaPwaInstall, useLivaPwaInstall } from "@dataliva/livalib";

Temel kullanım

Bileşen uygulamada bir kez, teklifin görünmesini istediğiniz yere (ör. giriş sayfası ya da kök layout) eklenir. document.body içine portal ile, ekranın altına (position="top" ile üstüne) sabitlenmiş olarak çizilir. Telefonda kenardan kenara bir çubuk, 576px ve üzeri genişlikte sağ köşeye oturan en fazla 420px'lik bir kart olur; 400px'ten dar ekranlarda açıklama gizlenir ve buton tam genişliğe iner. Alt/üst boşluk iOS'un güvenli alanını (safe-area-inset) hesaba katar.

import { LivaPwaInstall } from "@dataliva/livalib";
import logo from "./assets/logo.png";

<LivaPwaInstall appName="LivaBudget" icon={<img src={logo} alt="LivaBudget" />} />

Bu sitede çalışan bir banner örneği yoktur: dokümantasyon sitesinin web app manifest'i olmadığı için tarayıcı kurulum olayını hiç tetiklemez ve bileşen (iOS dışında) görünmez. Bileşen önizleme amaçlı zorla gösterilemez; aşağıdaki canlı örnek bu yüzden hook'un döndürdüğü durumu gösterir.

Banner ne zaman görünür

Banner, delayMs (varsayılan 1500 ms) dolduktan sonra ve aşağıdaki koşulların hepsi sağlandığında çizilir (shouldOffer):

  • Kurulu değil — bu oturumda appinstalled olayı görülmedi ve sayfa kurulu kabuk içinde açılmadı (display-mode standalone, fullscreen ya da minimal-ui değil; iOS'ta navigator.standalone değil; android-app:// yönlendiricisinden gelinmedi).
  • Ertelenmemiş — kullanıcı kapat (×) butonuna basmadı ya da basalı remindAfterDays gün geçti.
  • Platform listede — cihaz platforms listesindeki bir platform. Varsayılan ['ios', 'android'] olduğu için masaüstünde varsayılan olarak görünmez.
  • Kurulum yolu var — tarayıcı beforeinstallprompt olayını tetikledi (isPromptAvailable) ya da cihaz iOS ve adımların anlatılması gerekiyor (needsManualSteps). iOS'ta uygulama içi tarayıcılarda (Facebook, Instagram, Line, Twitter, WeChat) needsManualSteps false olduğundan teklif gösterilmez.

Platform userAgent'tan belirlenir; kendini masaüstü Safari gibi tanıtan iPadOS 13+ dokunma noktası sayısından ayırt edilip ios sayılır.

Butonların davranışı

  • Yükle — Tarayıcı olayı yakalanmışsa yerel diyaloğu açar ve kullanıcının seçimini ('accepted' / 'dismissed') döner. Olay tek kullanımlıktır; diyalog kapandıktan sonra banner, tarayıcı olayı yeniden tetikleyene kadar (genellikle bir sonraki sayfa yüklemesi) kaybolur. Kurulum kabul edilirse isInstalled true olur. iOS'ta sonuç 'manual' olur ve adım penceresi açılır; banner açık kalır. Diğer durumlarda 'unavailable' döner. Sonuç onInstall(result) ile bildirilir.
  • Kapat (×) — Teklifi erteler: zaman damgası storageKey anahtarıyla localStorage'a yazılır ve teklif remindAfterDays gün sonra yeniden görünür (0 = bir daha sorma). Ardından onDismiss çağrılır. Tarayıcının yerel diyaloğundaki "İptal" erteleme sayılmaz. localStorage erişilemiyorsa (gizli sekme, engellenmiş depolama) erteleme yalnızca sayfa açık kaldığı sürece geçerli olur; sonraki açılışta teklif yeniden görünür.

Türkçe metinler ve sade görünüm

Bileşenin yerleşik metinleri İngilizcedir (Install Liva, Install App, Not now…); Türkçe arayüzde i18n ile verilmelidir. appName yalnızca i18n.title verilmediğinde başlıkta (Install <appName>) kullanılır.

compact banner'da yalnızca simge ile kurulum butonunu bırakır; başlık ve açıklama çizilmez, başlık banner'ın erişilebilirlik etiketi olarak kalır. iOS adım metinlerindeki {icon} belirteci ilgili simgeyle (Paylaş, Ana Ekrana Ekle, Ekle) değiştirilir; çeviride simgenin cümledeki yeri bu sayede kaydırılabilir. Adım penceresinin başlığı yalnızca instructionsTitle verildiğinde çizilir. LivaBudget giriş sayfası bileşeni şöyle kullanır:

<LivaPwaInstall
  appName="LivaBudget"
  icon={<img src={logoIcon} alt="LivaBudget" />}
  storageKey="livabudget-pwa-install-dismissed"
  remindAfterDays={14}
  compact
  i18n={{
    // compact modda çizilmez; banner'ın erişilebilirlik etiketi olur
    title: "LivaBudget'ı Yükle",
    installText: "Uygulamayı Yükle",
    dismissText: "Şimdi değil",
    instructionsTitle: "Ana ekrana eklemek için",
    iosStep1: "Safari'de alttaki {icon} Paylaş butonuna dokunun",
    iosStep2: '"Ana Ekrana Ekle" seçeneğine dokunun',
    iosStep3: 'Sağ üstteki "Ekle" butonuna dokunun',
    gotItText: "Anladım",
  }}
/>

Aynı origin'de birden fazla uygulama çalışıyorsa her birine ayrı bir storageKey verin; aksi hâlde birinde yapılan erteleme diğerini de susturur.

Not: Adım metinleri iOS tarayıcısına göre değişmez (varsayılan metin Safari'yi anlatır). Chrome ya da Firefox için farklı metin göstermek isterseniz hook'un döndürdüğü iosBrowser değerine göre i18n'i kendiniz seçebilirsiniz.

Masaüstünde de teklif etmek

platforms listesine 'desktop' eklenirse teklif, kurulabilir durumdaki masaüstü Chromium tarayıcılarında da görünür.

<LivaPwaInstall
  appName="LivaBudget"
  platforms={["ios", "android", "desktop"]}
  position="top"
  delayMs={3000}
  onInstall={(result) => console.log("PWA kurulum sonucu:", result)}
  onDismiss={() => console.log("Kurulum teklifi ertelendi")}
/>

useLivaPwaInstall

Banner'ın kullandığı durum hook'u; kendi arayüzünüzü (ör. kullanıcı menüsünde kalıcı bir "Uygulamayı yükle" satırı) kurmak için doğrudan kullanılabilir. Aşağıdaki örnek hook'u 'desktop' dahil tüm platformlarla çağırır ve şu anki tarayıcınızın değerlerini gösterir. Bu sitede manifest olmadığı için masaüstünde ve Android'de isPromptAvailable false'tur ve install() 'unavailable' döner; iPhone/iPad Safari'de ise needsManualSteps true olur ve install() 'manual' döner. dismiss() ve resetDismissal() erteleme kaydını yazar/siler; isDismissed ve shouldOffer anında güncellenir.

useLivaPwaInstall — bu tarayıcıdaki durum
Önizleme yükleniyor…

shouldOffer erteleme ve platform koşullarını da içerir. Kullanıcının ertelemesinden etkilenmemesi gereken kalıcı bir menü öğesi için tekil alanları kullanın:

import { useLivaPwaInstall } from "@dataliva/livalib";

function InstallMenuItem({ onShowIosSteps }: { onShowIosSteps: () => void }) {
  const pwa = useLivaPwaInstall();

  if (pwa.isInstalled || (!pwa.isPromptAvailable && !pwa.needsManualSteps)) return null;

  return (
    <button
      type="button"
      onClick={async () => {
        const result = await pwa.install();
        if (result === "manual") onShowIosSteps(); // iOS: adımları kendi pencerenizde anlatın
      }}
    >
      Uygulamayı yükle
    </button>
  );
}

platforms seçeneği yalnızca shouldOffer'ı etkiler; isPromptAvailable, needsManualSteps ve isInstalled her platformda doğru değeri taşır.

Kurulum olayının yakalanması

beforeinstallprompt sayfa başına bir kez ve erken tetiklenir; React ağacı kurulana kadar beklenirse kaçar. Bu yüzden livalib, modül yüklenir yüklenmez window'a dinleyici bağlar (primeLivaPwaInstall), olayı saklar ve preventDefault() ile tarayıcının kendi otomatik kurulum teklifini bastırır. Durum modül düzeyinde tutulduğu için aynı sayfadaki tüm hook örnekleri ve banner aynı olayı paylaşır; appinstalled olayı hepsinde isInstalled'ı true yapar.

Önemli: Dinleyici LivaPwaInstall kullanılmasa bile livalib import edildiği anda bağlanır. Yani livalib kullanan her uygulamada tarayıcının otomatik kurulum teklifi (Android Chrome'daki mini bilgi çubuğu) görünmez; kurulum teklifi bu bileşen ya da hook ile sunulmalıdır.

livalib geç yüklenen bir chunk içindeyse olay chunk yüklenmeden tetiklenip kaçabilir. Bu durumda primeLivaPwaInstall()'ı uygulamanın giriş dosyasında erkenden çağırın; birden fazla çağrı güvenlidir:

// main.tsx
import { primeLivaPwaInstall } from "@dataliva/livalib";

primeLivaPwaInstall();

Uygulama tarafında gerekenler

Bileşen manifest üretmez ve service worker kaydetmez; yalnızca tarayıcının verdiği kurulum olayını yönetir. Chromium'un beforeinstallprompt olayını tetiklemesi için uygulamanın tarayıcının kurulabilirlik ölçütlerini karşılaması gerekir: HTTPS (geliştirmede localhost) üzerinden sunulmalı ve name / short_name, icons, start_url ile display alanlarını içeren bir web app manifest'i bulunmalıdır. LivaBudget'ta manifest ve service worker vite-plugin-pwa ile üretilir.

Manifest'teki display değerini standalone (ya da fullscreen / minimal-ui) yapın: bileşen kurulu açılışı bu display-mode medya sorgularıyla tanır ve ana ekrandan açılan uygulamada teklifi göstermez.