HOSTING CEPATDOMAIN MURAHSSL GRATISSUPPORT 24/7UPTIME 99.9%SERVER INDONESIAHOSTING CEPATDOMAIN MURAHSSL GRATISSUPPORT 24/7UPTIME 99.9%SERVER INDONESIA
Web Development

Cara Membuat PWA (Progressive Web App): Panduan Lengkap 2026

Tim HostingEkspres|14 Mei 2026|14 menit baca
cara membuat pwaprogressive web appservice workerweb manifestnext.js pwaoffline web applighthouse audit
Cara Membuat PWA (Progressive Web App): Panduan Lengkap 2026
Baca juga: Cara Membuat Aplikasi Web | Jamstack Hosting | Cara Membuat Rest Api | Cara Membuat Website

Cara Membuat PWA: Dari Website Biasa Menjadi Aplikasi yang Bisa Diinstall

Cara membuat PWA (Progressive Web App) sebenarnya bisa dilakukan dengan menambahkan beberapa komponen ke website yang sudah ada. Tidak perlu memulai dari nol. Dengan dua file tambahan - manifest.json dan Service Worker - website Anda bisa bertransformasi menjadi aplikasi yang bisa diinstall, bekerja offline, dan mengirim push notification.

Panduan cara membuat PWA ini dirancang untuk developer dengan pemahaman dasar HTML, CSS, dan JavaScript. Kita akan membangun PWA dari nol secara berurutan: mulai dari setup dasar, Service Worker dengan berbagai strategi caching, Web App Manifest, push notification, hingga audit Lighthouse untuk memastikan PWA Anda memenuhi semua standar Google. Di akhir panduan, kita juga akan membahas cara membuat PWA menggunakan framework Next.js yang sangat populer.

Prasyarat Sebelum Membuat PWA

Sebelum memulai cara membuat PWA, pastikan Anda memiliki:

cara membuat pwa
Ilustrasi cara membuat pwa
  • HTTPS aktif: Service Worker hanya berjalan di HTTPS. Untuk development lokal, localhost diizinkan.
  • Text editor: VS Code sangat direkomendasikan dengan ekstensi PWA Tools.
  • Node.js terinstall untuk menjalankan server lokal.
  • Chrome DevTools: Untuk debugging Service Worker dan audit Lighthouse.
  • Pemahaman dasar JavaScript: Terutama Promise dan async/await.

Langkah 1: Struktur Project PWA

Mari mulai cara membuat PWA dengan menyiapkan struktur folder yang rapi:

my-pwa/
├── index.html          # Halaman utama
├── manifest.json       # Web App Manifest
├── sw.js               # Service Worker
├── css/
│   └── style.css
├── js/
│   └── app.js          # JavaScript utama aplikasi
└── icons/
    ├── icon-72x72.png
    ├── icon-96x96.png
    ├── icon-128x128.png
    ├── icon-144x144.png
    ├── icon-152x152.png
    ├── icon-192x192.png
    ├── icon-384x384.png
    └── icon-512x512.png

Ikon dalam berbagai ukuran diperlukan untuk memastikan ikon tampil tajam di berbagai ukuran layar dan device. Gunakan tool seperti realfavicongenerator.net untuk generate semua ukuran sekaligus dari satu file ikon.

Langkah 2: Buat Web App Manifest

Web App Manifest adalah file JSON yang memberitahu browser bagaimana aplikasi Anda seharusnya berperilaku saat diinstall. Ini adalah langkah cara membuat PWA yang paling mudah:

// manifest.json
{
  "name": "Nama Lengkap Aplikasi Anda",
  "short_name": "NamaApp",
  "description": "Deskripsi singkat aplikasi Anda yang informatif",
  "start_url": "/",
  "scope": "/",
  "display": "standalone",
  "orientation": "portrait-primary",
  "background_color": "#ffffff",
  "theme_color": "#3b82f6",
  "lang": "id",
  "dir": "ltr",
  "categories": ["productivity", "utilities"],
  "icons": [
    { "src": "/icons/icon-72x72.png",   "sizes": "72x72",   "type": "image/png", "purpose": "any maskable" },
    { "src": "/icons/icon-96x96.png",   "sizes": "96x96",   "type": "image/png", "purpose": "any maskable" },
    { "src": "/icons/icon-128x128.png", "sizes": "128x128", "type": "image/png", "purpose": "any maskable" },
    { "src": "/icons/icon-144x144.png", "sizes": "144x144", "type": "image/png", "purpose": "any maskable" },
    { "src": "/icons/icon-152x152.png", "sizes": "152x152", "type": "image/png", "purpose": "any maskable" },
    { "src": "/icons/icon-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" },
    { "src": "/icons/icon-384x384.png", "sizes": "384x384", "type": "image/png", "purpose": "any maskable" },
    { "src": "/icons/icon-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
  ],
  "shortcuts": [
    {
      "name": "Buat Baru",
      "short_name": "Buat",
      "url": "/buat-baru",
      "icons": [{ "src": "/icons/shortcut-baru.png", "sizes": "96x96" }]
    }
  ],
  "screenshots": [
    {
      "src": "/screenshots/home-mobile.png",
      "sizes": "390x844",
      "type": "image/png",
      "form_factor": "narrow",
      "label": "Halaman Utama"
    }
  ]
}

Penjelasan properti penting:

  • display: "standalone" - Aplikasi berjalan tanpa address bar browser, persis seperti native app. Alternatif: "fullscreen" (tanpa status bar) atau "minimal-ui" (dengan kontrol navigasi minimal).
  • start_url - URL yang dibuka saat pengguna meluncurkan aplikasi dari homescreen. Tambahkan query string untuk tracking: "/?source=pwa".
  • purpose: "any maskable" - Ikon mendukung maskable format (adaptive icon Android) sekaligus tampilan biasa.
  • shortcuts - Pintasan yang muncul saat pengguna long-press ikon aplikasi (Android).

Langkah 3: Hubungkan Manifest ke HTML

Tambahkan tag link manifest dan meta tag yang diperlukan ke <head> HTML Anda:

<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Aplikasi PWA Saya</title>

  <!-- Web App Manifest -->
  <link rel="manifest" href="/manifest.json">

  <!-- Theme color untuk browser chrome -->
  <meta name="theme-color" content="#3b82f6">

  <!-- Apple-specific meta tags untuk iOS -->
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="default">
  <meta name="apple-mobile-web-app-title" content="NamaApp">
  <link rel="apple-touch-icon" href="/icons/icon-192x192.png">

  <!-- Microsoft tiles -->
  <meta name="msapplication-TileImage" content="/icons/icon-144x144.png">
  <meta name="msapplication-TileColor" content="#3b82f6">

  <link rel="stylesheet" href="/css/style.css">
</head>
<body>
  <div id="app">
    <!-- Konten aplikasi Anda -->
  </div>
  <script src="/js/app.js"></script>
</body>
</html>

Langkah 4: Buat Service Worker

Ini adalah bagian paling penting dalam cara membuat PWA. Service Worker adalah proxy jaringan yang berjalan di background dan mengontrol semua request/response.

Strategi Caching yang Umum Digunakan

Pilih strategi caching berdasarkan jenis konten:

  • Cache First (Cache Falling Back to Network): Ideal untuk aset statis (CSS, JS, gambar). Cek cache dulu, jika tidak ada baru ke network.
  • Network First (Network Falling Back to Cache): Ideal untuk konten dinamis (API responses, halaman yang sering berubah). Coba network dulu, jika gagal gunakan cache.
  • Stale While Revalidate: Kembalikan cache segera, lalu perbarui cache di background. Keseimbangan antara kecepatan dan kesegaran data.
  • Cache Only: Hanya dari cache. Cocok untuk aset yang tidak pernah berubah.
  • Network Only: Hanya dari network. Cocok untuk request yang tidak perlu di-cache.
// sw.js - Service Worker Lengkap

const CACHE_NAME = 'my-pwa-v1';
const STATIC_CACHE = 'static-v1';
const DYNAMIC_CACHE = 'dynamic-v1';

// Aset yang di-precache saat install
const STATIC_ASSETS = [
  '/',
  '/index.html',
  '/css/style.css',
  '/js/app.js',
  '/icons/icon-192x192.png',
  '/offline.html',  // Halaman yang ditampilkan saat offline
];

// === INSTALL: Precache static assets ===
self.addEventListener('install', (event) => {
  console.log('[SW] Installing...');
  event.waitUntil(
    caches.open(STATIC_CACHE)
      .then((cache) => {
        console.log('[SW] Precaching static assets');
        return cache.addAll(STATIC_ASSETS);
      })
      .then(() => self.skipWaiting()) // Aktifkan SW baru segera
  );
});

// === ACTIVATE: Hapus cache lama ===
self.addEventListener('activate', (event) => {
  console.log('[SW] Activating...');
  event.waitUntil(
    caches.keys().then((cacheNames) => {
      return Promise.all(
        cacheNames
          .filter((name) => name !== STATIC_CACHE && name !== DYNAMIC_CACHE)
          .map((name) => {
            console.log('[SW] Deleting old cache:', name);
            return caches.delete(name);
          })
      );
    }).then(() => self.clients.claim()) // Ambil kontrol semua halaman segera
  );
});

// === FETCH: Intercept semua network request ===
self.addEventListener('fetch', (event) => {
  const { request } = event;
  const url = new URL(request.url);

  // Jangan intercept request ke domain lain
  if (url.origin !== location.origin) return;

  // Strategi untuk API requests: Network First
  if (url.pathname.startsWith('/api/')) {
    event.respondWith(networkFirst(request));
    return;
  }

  // Strategi untuk aset statis: Cache First
  if (
    request.destination === 'style' ||
    request.destination === 'script' ||
    request.destination === 'image'
  ) {
    event.respondWith(cacheFirst(request));
    return;
  }

  // Strategi default untuk navigasi: Stale While Revalidate
  event.respondWith(staleWhileRevalidate(request));
});

// === Cache First Strategy ===
async function cacheFirst(request) {
  const cachedResponse = await caches.match(request);
  if (cachedResponse) return cachedResponse;

  try {
    const networkResponse = await fetch(request);
    if (networkResponse.ok) {
      const cache = await caches.open(STATIC_CACHE);
      cache.put(request, networkResponse.clone());
    }
    return networkResponse;
  } catch {
    return new Response('Aset tidak tersedia offline', { status: 503 });
  }
}

// === Network First Strategy ===
async function networkFirst(request) {
  try {
    const networkResponse = await fetch(request);
    if (networkResponse.ok) {
      const cache = await caches.open(DYNAMIC_CACHE);
      cache.put(request, networkResponse.clone());
    }
    return networkResponse;
  } catch {
    const cachedResponse = await caches.match(request);
    return cachedResponse || new Response(
      JSON.stringify({ error: 'Offline', message: 'Tidak ada koneksi internet' }),
      { status: 503, headers: { 'Content-Type': 'application/json' } }
    );
  }
}

// === Stale While Revalidate Strategy ===
async function staleWhileRevalidate(request) {
  const cache = await caches.open(DYNAMIC_CACHE);
  const cachedResponse = await cache.match(request);

  const fetchPromise = fetch(request).then((networkResponse) => {
    if (networkResponse.ok) cache.put(request, networkResponse.clone());
    return networkResponse;
  }).catch(() => null);

  return cachedResponse || fetchPromise || caches.match('/offline.html');
}

Langkah 5: Daftarkan Service Worker di JavaScript

// js/app.js

// Daftarkan Service Worker
if ('serviceWorker' in navigator) {
  window.addEventListener('load', async () => {
    try {
      const registration = await navigator.serviceWorker.register('/sw.js', {
        scope: '/'
      });

      console.log('Service Worker terdaftar:', registration.scope);

      // Cek update SW
      registration.addEventListener('updatefound', () => {
        const newWorker = registration.installing;
        newWorker.addEventListener('statechange', () => {
          if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
            // Ada versi baru, tampilkan notifikasi ke pengguna
            showUpdateNotification();
          }
        });
      });
    } catch (error) {
      console.error('Gagal mendaftarkan Service Worker:', error);
    }
  });
}

// Tampilkan prompt install PWA
let deferredPrompt;

window.addEventListener('beforeinstallprompt', (event) => {
  event.preventDefault();
  deferredPrompt = event;
  showInstallButton(); // Tampilkan tombol install kustom
});

function showInstallButton() {
  const installBtn = document.getElementById('install-btn');
  if (installBtn) {
    installBtn.style.display = 'block';
    installBtn.addEventListener('click', async () => {
      if (!deferredPrompt) return;
      deferredPrompt.prompt();
      const { outcome } = await deferredPrompt.userChoice;
      console.log('Pilihan pengguna:', outcome); // 'accepted' atau 'dismissed'
      deferredPrompt = null;
      installBtn.style.display = 'none';
    });
  }
}

// Event setelah PWA berhasil diinstall
window.addEventListener('appinstalled', () => {
  console.log('PWA berhasil diinstall!');
  // Kirim event analitik
});
cara membuat pwa
Ilustrasi cara membuat pwa

Langkah 6: Tambahkan Push Notification

Push notification adalah fitur PWA yang paling powerful untuk reengagement pengguna. Implementasinya memerlukan server-side component. Berikut cara membuat PWA dengan push notification menggunakan Web Push Protocol:

// Di app.js - minta izin notifikasi
async function requestNotificationPermission() {
  if (!('Notification' in window) || !('PushManager' in window)) {
    console.log('Browser tidak mendukung push notification');
    return;
  }

  const permission = await Notification.requestPermission();
  if (permission === 'granted') {
    await subscribeToPush();
  }
}

async function subscribeToPush() {
  const registration = await navigator.serviceWorker.ready;
  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array('YOUR_VAPID_PUBLIC_KEY')
  });

  // Kirim subscription ke server Anda
  await fetch('/api/push/subscribe', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(subscription)
  });
}

// Utility function
function urlBase64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - base64String.length % 4) % 4);
  const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
  const rawData = atob(base64);
  return new Uint8Array([...rawData].map(char => char.charCodeAt(0)));
}

// Di sw.js - tampilkan notifikasi saat menerima push
self.addEventListener('push', (event) => {
  const data = event.data?.json() ?? {};
  const options = {
    body: data.body || 'Ada notifikasi baru untuk Anda',
    icon: '/icons/icon-192x192.png',
    badge: '/icons/badge-72x72.png',
    data: { url: data.url || '/' },
    actions: [
      { action: 'open', title: 'Buka' },
      { action: 'dismiss', title: 'Abaikan' }
    ]
  };

  event.waitUntil(
    self.registration.showNotification(data.title || 'Notifikasi', options)
  );
});

// Handle klik pada notifikasi
self.addEventListener('notificationclick', (event) => {
  event.notification.close();
  if (event.action === 'open' || !event.action) {
    event.waitUntil(
      clients.openWindow(event.notification.data.url)
    );
  }
});

Langkah 7: Cara Membuat PWA dengan Next.js

Jika Anda menggunakan Next.js - framework React yang sangat populer - cara membuat PWA menjadi jauh lebih mudah dengan package next-pwa:

# Install next-pwa
npm install next-pwa

# atau dengan pnpm
pnpm add next-pwa
// next.config.ts
import withPWA from 'next-pwa';

const config = withPWA({
  dest: 'public',           // SW akan digenerate di folder public
  register: true,           // Otomatis daftarkan SW
  skipWaiting: true,        // Aktifkan SW baru segera
  disable: process.env.NODE_ENV === 'development', // Nonaktifkan di dev
  runtimeCaching: [
    {
      urlPattern: /^https://fonts.googleapis.com/.*/i,
      handler: 'CacheFirst',
      options: {
        cacheName: 'google-fonts-cache',
        expiration: { maxEntries: 10, maxAgeSeconds: 60 * 60 * 24 * 365 },
        cacheableResponse: { statuses: [0, 200] },
      },
    },
    {
      urlPattern: /^https://your-api.com/api/.*/i,
      handler: 'NetworkFirst',
      options: {
        cacheName: 'api-cache',
        expiration: { maxEntries: 32, maxAgeSeconds: 60 * 5 },
        networkTimeoutSeconds: 10,
      },
    },
  ],
});

export default config({ /* konfigurasi Next.js lainnya */ });
// public/manifest.json (untuk Next.js)
{
  "name": "Aplikasi Next.js PWA",
  "short_name": "NextPWA",
  "description": "Aplikasi Next.js dengan dukungan PWA penuh",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#3b82f6",
  "icons": [
    { "src": "/icons/icon-192x192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icons/icon-512x512.png", "sizes": "512x512", "type": "image/png" }
  ]
}
// app/layout.tsx - tambahkan manifest link dan meta tags
import type { Metadata } from 'next';

export const metadata: Metadata = {
  manifest: '/manifest.json',
  themeColor: '#3b82f6',
  appleWebApp: {
    capable: true,
    statusBarStyle: 'default',
    title: 'NextPWA',
  },
  formatDetection: { telephone: false },
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="id">
      <body>{children}</body>
    </html>
  );
}

Langkah 8: Audit PWA dengan Lighthouse

Setelah semua komponen selesai, cara membuat PWA yang benar harus divalidasi menggunakan Lighthouse - tool audit bawaan Chrome DevTools:

  1. Buka website Anda di Chrome.
  2. Tekan F12 untuk buka DevTools.
  3. Klik tab Lighthouse.
  4. Centang Progressive Web App di bagian Categories.
  5. Klik Analyze page load.

Lighthouse akan memeriksa checklist berikut dan memberikan skor serta rekomendasi perbaikan:

  • HTTPS aktif
  • Service Worker terdaftar dan mengontrol halaman
  • Web App Manifest valid dengan semua field wajib
  • Bisa dimuat saat offline (setidaknya response 200)
  • Ikon 192x192 dan 512x512 ada di manifest
  • Start URL bisa dimuat saat offline
  • Viewport meta tag ada
  • Tidak ada konten HTTP di halaman HTTPS (mixed content)
Target Skor: Usahakan skor PWA 100/100 di Lighthouse. Skor performa di atas 90 juga penting karena mempengaruhi pengalaman pengguna dan SEO secara langsung.

Hosting PWA: Apa yang Perlu Diperhatikan

Cara membuat PWA yang baik juga harus diimbangi dengan hosting yang tepat. Beberapa hal yang perlu diperhatikan:

  • HTTPS wajib: Pastikan hosting Anda mendukung SSL. Tanpa HTTPS, Service Worker tidak berjalan dan PWA Anda tidak berfungsi.
  • HTTP/2 atau HTTP/3: Mendukung multiplexing request yang mempercepat loading PWA secara signifikan.
  • Compression: Gzip atau Brotli compression untuk memperkecil ukuran file JS dan CSS.
  • Cache headers yang benar: Server perlu mengirim header Cache-Control yang tepat agar browser dan Service Worker bisa bekerja optimal.
  • CDN: Distribusikan aset statis ke CDN untuk loading lebih cepat dari berbagai lokasi.
Hosting untuk PWA: HostingEkspres menyediakan SSL gratis, server SSD NVMe di Indonesia, dukungan HTTP/2, dan Gzip/Brotli compression - semua yang dibutuhkan PWA Anda untuk performa optimal.

Troubleshooting: Masalah Umum Saat Membuat PWA

  • Service Worker tidak terdaftar: Pastikan file sw.js berada di root domain, bukan subfolder. Service Worker hanya bisa mengontrol halaman yang berada di scope-nya.
  • Install prompt tidak muncul: Browser hanya menampilkan install prompt jika pengguna sudah mengunjungi website minimal dua kali dalam 5 menit terakhir, manifest valid, dan Service Worker aktif. Cek tab Application di DevTools.
  • Cache tidak terupdate: Pastikan Anda mengubah nama CACHE_NAME setiap kali ada update signifikan. Browser akan menggunakan cache lama jika nama sama.
  • iOS tidak bisa install: Safari iOS tidak menampilkan install prompt otomatis. Tambahkan instruksi manual: "Ketuk ikon Share > Add to Home Screen". Gunakan meta tag apple-mobile-web-app-capable.
  • Mixed content error: Semua resource (gambar, skrip, CSS) harus dimuat via HTTPS. Resource HTTP di halaman HTTPS akan diblokir browser.

FAQ: Pertanyaan Seputar Cara Membuat PWA

Apakah saya harus membuat ulang website dari nol untuk menjadi PWA?

Tidak sama sekali. PWA bisa ditambahkan ke website yang sudah ada dengan menambahkan file manifest.json dan Service Worker (sw.js). Proses migrasi bisa dilakukan secara bertahap - mulai dari manifest dan caching dasar, lalu tambahkan fitur seperti offline support dan push notification seiring waktu.

Apakah Service Worker bisa menyebabkan bug pada website?

Ya, jika tidak dikonfigurasi dengan benar. Bug paling umum adalah cache yang "terjebak" - pengguna melihat versi lama website karena cache tidak terupdate. Solusinya: selalu update CACHE_NAME saat ada perubahan signifikan, dan implementasikan logika update yang memberi tahu pengguna saat versi baru tersedia.

Berapa ukuran ideal Service Worker?

Service Worker yang baik seharusnya kecil dan ringan - idealnya di bawah 50KB uncompressed. Jangan masukkan library besar ke dalam SW. Untuk proyek kompleks, gunakan Workbox dari Google yang mengoptimalkan ukuran dan performa SW secara otomatis.

Apakah PWA bisa muncul di Google Play Store atau App Store?

Ya. Google mendukung TWA (Trusted Web Activities) yang memungkinkan PWA dipublikasikan di Google Play Store sebagai "aplikasi" yang sesungguhnya - pengguna bisa mengunduhnya dari Play Store. Untuk Apple App Store, prosesnya lebih rumit dan memerlukan wrapping tambahan, tapi secara teknis bisa dilakukan.

Apakah PWA bisa mengakses kamera, mikrofon, dan GPS?

Ya, dengan izin pengguna. PWA bisa mengakses kamera dan mikrofon via MediaDevices API, GPS via Geolocation API, accelerometer via DeviceMotion API, dan banyak sensor lain. Akses ke hardware lebih terbatas dibanding aplikasi native, tapi untuk sebagian besar use case sudah sangat mencukupi.

Apa itu Workbox dan apakah perlu digunakan?

Workbox adalah library resmi dari Google yang menyederhanakan pembuatan Service Worker. Alih-alih menulis logika caching dari nol, Workbox menyediakan strategi caching siap pakai, background sync, dan banyak utilitas lainnya. Untuk proyek production skala besar, sangat direkomendasikan. Next.js dengan next-pwa sudah menggunakan Workbox di balik layar.

Bagaimana cara mengukur performa PWA setelah deploy?

Gunakan kombinasi tools berikut: Lighthouse untuk audit PWA dan performa, Chrome DevTools Application tab untuk inspect Service Worker dan cache, Web Vitals extension untuk monitoring Core Web Vitals (LCP, FID, CLS) secara real-time, dan Google Search Console untuk memonitor performa di hasil pencarian. Google Analytics 4 juga bisa dikonfigurasi untuk melacak instalasi PWA dan sesi yang datang dari homescreen.

Kesimpulan: Mulai Cara Membuat PWA Sekarang

Cara membuat PWA tidak sesulit yang dibayangkan. Dengan menambahkan Web App Manifest dan Service Worker ke website yang sudah ada, Anda bisa memberikan pengalaman yang jauh lebih baik kepada pengguna - loading lebih cepat, bisa offline, installable, dan bisa mengirim notifikasi.

Ringkasan langkah cara membuat PWA:

  1. Siapkan struktur folder dan ikon dalam berbagai ukuran
  2. Buat file manifest.json yang valid
  3. Hubungkan manifest ke HTML dengan tag link dan meta tags yang diperlukan
  4. Tulis Service Worker (sw.js) dengan strategi caching yang sesuai
  5. Daftarkan Service Worker dan implementasikan install prompt di JavaScript
  6. Tambahkan push notification jika diperlukan
  7. Audit dengan Lighthouse dan pastikan skor PWA 100/100
  8. Deploy ke hosting dengan HTTPS aktif

Ingat, HTTPS adalah syarat mutlak untuk PWA. Pastikan hosting Anda mendukungnya. HostingEkspres.com menyediakan SSL gratis untuk semua paket hosting, server Indonesia dengan SSD NVMe untuk performa optimal, dan support 24/7 - fondasi yang tepat untuk PWA Anda melayani pengguna dengan pengalaman terbaik.

Deploy PWA Anda dengan Hosting Berkualitas

SSL gratis, server SSD NVMe Indonesia, uptime 99.9%, HTTP/2, dan support 24/7. Mulai dari Rp 15.000/bulan.

Lihat Paket Hosting

Butuh Hosting untuk Website Anda?

Dapatkan hosting cepat, aman, dan terpercaya dengan harga terjangkau. Gratis domain, SSL, dan support 24/7.

Jangan Ketinggalan Promo!

Subscribe newsletter kami dan dapatkan diskon hingga 50% untuk pembelian pertama kamu.

Gratis, tanpa spam. Bisa unsubscribe kapan saja.