<header class="flex items-center">

<NuxtImg src="logo.png" class="w-18" alt="Dywan Dev - Digital tools & templates" format="webp" quality="80" loading="lazy" />

<Item><nuxt-link href="/">Home</nuxt-link></Item>

<Item><nuxt-link href="/about">About</nuxt-link></Item>

<Item><nuxt-link href="/works"> Portfolio</nuxt-link></Item>

<Item><nuxt-link href="/contact_me"> Contact</nuxt-link></Item>

<a href="/contact-me" title="Get in touch with Dywan Dev"> Contact </a>

<themeswitch class="moon">Dark/Light</themeswitch>

<langswitch class="en">en/fa</langswitch>

</header>

<initilizecontent class="content">Hello World - Dywan Dev</initilizecontent>

<myname is="Dywan Dev" />

<jobtitle is="Digital tools · Templates · Case studies" />

<portfolios are="ready" number="8" />

<experience years="more than 6" />

<birthdate year="1998" month="july" day="11" />

<skills :list="['NUXT', 'Vue', 'React', 'Next', 'Javascript','Responsive Design', 'i18n', 'TypeScript]" />

<contactDetails :list="['contact@dywandev.com', 'linkedin.com/in/dywan-dev', 'github.com/dywan-dev']" />

Dywan Dev
المدونة
كيف تضيف دعم PWA لتطبيق React + Vite في 2026

كيف تضيف دعم PWA لتطبيق React + Vite في 2026

مقدمة

أغلب المواقع تُحمّل. تطبيق الويب التقدّمي PWA يصمد.

عندما يفقد المستخدم اتصال الإنترنت، تُظهر تطبيقات React العادية شاشة فارغة أو خطأ. أما Progressive Web App فيواصل العمل — بتقديم صفحات مخبأة، والحفاظ على التجربة، والمزامنة عند عودة الاتصال.

إضافة دعم PWA لتطبيق React مع Vite من أقوى التحسينات التي يمكنك قدمها للأداء واحتفاظ المستخدمين ودرجات Lighthouse. يوضح هذا الدليل بالضبط كيف نفّذت ذلك في Dywan Dev وSavoura Dywan — بما في ذلك مطالبة التثبيت وصفحة عدم الاتصال وإشعار التحديث التي تتخطاها أغلب الشروحات.

ما هي PWA ولماذا يهم الأمر

تطبيق الويب التقدّمي Progressive Web App هو تطبيق ويب يتصرف مثل التطبيق الأصلي. يمكن تثبيته على جهاز المستخدم، والعمل دون اتصال، والتحميل فورًا في الزيارات التالية، وإرسال إشعارات دفع.

للشركات يعني ذلك معدلات ارتداد أقل وتفاعلًا أعلى. للمطورين يعني درجات Lighthouse أفضل وعرضًا منتجًا أقوى. لك كمستقل أو بائع قوالب — إنها ميزة يدفع العملاء من أجلها أكثر.

المتطلبات الثلاثة الأساسية لـ PWA هي: ملف manifest، وservice worker، وHTTPS. يجعل Vite الأمر مباشرًا بإضافة واحدة.

1. تثبيت إضافة Vite PWA

npm install -D vite-plugin-pwa

تتولى الإضافة توليد service worker وحقن الـ manifest تلقائيًا. تعتمد على Workbox — نفس المكتبة التي تستخدمها Google لأدوات PWA.

2. ضبط الإضافة في vite.config.js

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { VitePWA } from 'vite-plugin-pwa';

export default defineConfig({
  plugins: [
    react(),
    VitePWA({
      registerType: 'autoUpdate',
      includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'mask-icon.svg'],
      manifest: {
        name: 'Dywan Dev',
        short_name: 'DywanDev',
        description: 'Modern web templates and fullstack solutions',
        theme_color: '#0f172a',
        background_color: '#0f172a',
        display: 'standalone',
        scope: '/',
        start_url: '/',
        icons: [
          {
            src: 'pwa-192x192.png',
            sizes: '192x192',
            type: 'image/png'
          },
          {
            src: 'pwa-512x512.png',
            sizes: '512x512',
            type: 'image/png'
          },
          {
            src: 'pwa-512x512.png',
            sizes: '512x512',
            type: 'image/png',
            purpose: 'any maskable'
          }
        ]
      },
      workbox: {
        globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
        runtimeCaching: [
          {
            urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
            handler: 'CacheFirst',
            options: {
              cacheName: 'google-fonts-cache',
              expiration: {
                maxEntries: 10,
                maxAgeSeconds: 60 * 60 * 24 * 365
              }
            }
          }
        ]
      }
    })
  ]
});

استبدل الاسم والوصف ولون السمة بهويتك. يجب أن تكون الأيقونات في مجلد public/ — أنشئها من شعارك بأداة مثل PWA Asset Generator.

3. إنشاء صفحة احتياطية دون اتصال

هذا ما يميّز PWA الحقيقية عن إعداد service worker بسيط. عند انقطاع الإنترنت، اعرض شيئًا مفيدًا بدل خطأ المتصفح.

أنشئ public/offline.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>You're Offline</title>
  <style>
    body {
      font-family: sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      height: 100vh;
      margin: 0;
      background: #0f172a;
      color: #f8fafc;
      text-align: center;
      padding: 2rem;
    }
    h1 { font-size: 2rem; margin-bottom: 1rem; }
    p { color: #94a3b8; max-width: 400px; }
  </style>
</head>
<body>
  <h1>You're offline</h1>
  <p>It looks like you lost your connection. The page you're looking for will be available once you're back online.</p>
</body>
</html>

ثم أضف المرجع في إعدادات Workbox داخل vite.config.js (أضف navigateFallback بجانب أنماط globPatterns الحالية):

workbox: {
  navigateFallback: '/offline.html',
  globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}']
}

4. إضافة مطالبة التثبيت

تعرض المتصفحات مطالبة تثبيت أصلية — لكن يمكنك اعتراضها وعرض واجهتك في الوقت المناسب. يزيد ذلك معدلات التثبيت بشكل كبير.

أنشئ src/hooks/usePWAInstall.js:

import { useState, useEffect } from 'react';

export const usePWAInstall = () => {
  const [installPrompt, setInstallPrompt] = useState(null);
  const [isInstallable, setIsInstallable] = useState(false);

  useEffect(() => {
    const handler = (e) => {
      e.preventDefault();
      setInstallPrompt(e);
      setIsInstallable(true);
    };

    window.addEventListener('beforeinstallprompt', handler);
    return () => window.removeEventListener('beforeinstallprompt', handler);
  }, []);

  const install = async () => {
    if (!installPrompt) return;
    await installPrompt.prompt();
    const { outcome } = await installPrompt.userChoice;
    if (outcome === 'accepted') setIsInstallable(false);
    setInstallPrompt(null);
  };

  return { isInstallable, install };
};

استخدمه في أي مكوّن:

import { usePWAInstall } from './hooks/usePWAInstall';

export const InstallButton = () => {
  const { isInstallable, install } = usePWAInstall();

  if (!isInstallable) return null;

  return (
    <button onClick={install} className="install-btn">
      Install App
    </button>
  );
};

ضع الزر في شريط التنقل أو القسم البطل. يظهر فقط عندما يعتبر المتصفح التطبيق قابلًا للتثبيت — فلا يُعرض دون داعٍ.

5. إضافة إشعار التحديث

عند نشر إصدار جديد، لن يرى المستخدمون الذين يخزّنون service worker القديم التغييرات تلقائيًا. أظهر لهم إشعارًا لتحديث الصفحة والحصول على أحدث إصدار.

حدّث src/main.jsx:

import { registerSW } from 'virtual:pwa-register';

const updateSW = registerSW({
  onNeedRefresh() {
    const confirmed = window.confirm(
      'A new version is available. Reload to update?'
    );
    if (confirmed) updateSW(true);
  },
  onOfflineReady() {
    console.log('App is ready to work offline');
  }
});

لتجربة أنقى، استبدل window.confirm بإشعار toast مخصص باستخدام مكوّنات الواجهة لديك.

6. التحقق من أن كل شيء يعمل

شغّل البناء واعرضه محليًا:

npm run build
npm run preview

ثم افتح Chrome DevTools ← Application ← Service Workers. يجب أن ترى service worker مسجّلًا ونشطًا. راجع تبويب Manifest للتأكد من الأيقونات والبيانات الوصفية.

شغّل تدقيق Lighthouse. يجب أن تحقق PWA المضبوطة جيدًا درجات خضراء في الأداء وإمكانية الوصول وفئة PWA.

الخاتمة

دعم PWA من الميزات التي تستغرق ساعات قليلة للتنفيذ ويعود عليك باستمرار — بدرجات Lighthouse واحتفاظ المستخدمين وانطباع العملاء. عندما تخبر عميلًا أن موقعه يعمل دون اتصال ويمكن تثبيته على الهاتف مثل التطبيق الأصلي، تقترب الصفقة.

كل قالب أبنيه في Dywan Dev يشمل دعم PWA افتراضيًا. ليس إضافة اختيارية — بل معيار.

مطعم، معرض أعمال، أو موقع أعمال؟ قوالب Dywan Dev جاهزة لـ PWA ومتعددة اللغات ومحسّنة من البداية. استكشف القوالب.

تابع القراءة

عرض الكلعرض الكل
واتساب