Building Progressive Web Apps with Vue.js

Steps to create fast, reliable, and engaging Progressive Web Apps using Vue.js, including offline capabilities and push notifications.

0 likes
8 views

Rule Content

{
  "title": "Building Progressive Web Apps with Vue.js",
  "description": "Steps to create fast, reliable, and engaging Progressive Web Apps using Vue.js, including offline capabilities and push notifications.",
  "category": "Vue Cursor Rules",
  "rules": [
    {
      "name": "Enable PWA Support",
      "description": "Ensure the Vue.js project is configured as a Progressive Web App (PWA) to provide offline capabilities and enhanced performance.",
      "actions": [
        {
          "type": "command",
          "command": "vue add pwa"
        }
      ]
    },
    {
      "name": "Configure Service Worker",
      "description": "Set up a service worker to manage caching and offline functionality.",
      "actions": [
        {
          "type": "file",
          "path": "src/registerServiceWorker.js",
          "content": "if ('serviceWorker' in navigator) {\n  window.addEventListener('load', () => {\n    navigator.serviceWorker.register('/service-worker.js').then(\n      registration => {\n        console.log('Service Worker registered with scope:', registration.scope);\n      },\n      error => {\n        console.error('Service Worker registration failed:', error);\n      }\n    );\n  });\n}"
        }
      ]
    },
    {
      "name": "Optimize Performance with Lazy Loading",
      "description": "Implement lazy loading for routes and components to improve performance by loading only the necessary parts of the application on demand.",
      "actions": [
        {
          "type": "file",
          "path": "src/router/index.js",
          "content": "import { createRouter, createWebHistory } from 'vue-router';\nconst Home = () => import('../views/Home.vue');\nconst About = () => import('../views/About.vue');\nconst routes = [\n  { path: '/', name: 'Home', component: Home },\n  { path: '/about', name: 'About', component: About }\n];\nconst router = createRouter({\n  history: createWebHistory(),\n  routes\n});\nexport default router;"
        }
      ]
    },
    {
      "name": "Implement Push Notifications",
      "description": "Set up push notifications to engage users by sending timely updates.",
      "actions": [
        {
          "type": "file",
          "path": "src/firebase-messaging-sw.js",
          "content": "importScripts('https://www.gstatic.com/firebasejs/9.6.1/firebase-app-compat.js');\nimportScripts('https://www.gstatic.com/firebasejs/9.6.1/firebase-messaging-compat.js');\nfirebase.initializeApp({\n  apiKey: 'YOUR_API_KEY',\n  authDomain: 'YOUR_AUTH_DOMAIN',\n  projectId: 'YOUR_PROJECT_ID',\n  storageBucket: 'YOUR_STORAGE_BUCKET',\n  messagingSenderId: 'YOUR_MESSAGING_SENDER_ID',\n  appId: 'YOUR_APP_ID'\n});\nconst messaging = firebase.messaging();\nmessaging.onBackgroundMessage(payload => {\n  const notificationTitle = payload.notification.title;\n  const notificationOptions = {\n    body: payload.notification.body,\n    icon: '/firebase-logo.png'\n  };\n  self.registration.showNotification(notificationTitle, notificationOptions);\n});"
        },
        {
          "type": "file",
          "path": "src/main.js",
          "content": "import { initializeApp } from 'firebase/app';\nimport { getMessaging, getToken, onMessage } from 'firebase/messaging';\nconst firebaseConfig = {\n  apiKey: 'YOUR_API_KEY',\n  authDomain: 'YOUR_AUTH_DOMAIN',\n  projectId: 'YOUR_PROJECT_ID',\n  storageBucket: 'YOUR_STORAGE_BUCKET',\n  messagingSenderId: 'YOUR_MESSAGING_SENDER_ID',\n  appId: 'YOUR_APP_ID'\n};\nconst app = initializeApp(firebaseConfig);\nconst messaging = getMessaging(app);\ngetToken(messaging, { vapidKey: 'YOUR_VAPID_KEY' }).then(currentToken => {\n  if (currentToken) {\n    console.log('Token:', currentToken);\n  } else {\n    console.log('No registration token available. Request permission to generate one.');\n  }\n}).catch(err => {\n  console.log('An error occurred while retrieving token. ', err);\n});\nonMessage(messaging, payload => {\n  console.log('Message received. ', payload);\n});"
        }
      ]
    },
    {
      "name": "Optimize Images and Assets",
      "description": "Use modern image formats and optimize assets to improve load times and performance.",
      "actions": [
        {
          "type": "file",
          "path": "public/index.html",
          "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Vue PWA</title>\n  <link rel=\"icon\" href=\"/favicon.ico\">\n  <link rel=\"manifest\" href=\"/manifest.json\">\n  <link rel=\"apple-touch-icon\" href=\"/icons/icon-192x192.png\">\n  <meta name=\"theme-color\" content=\"#4DBA87\">\n</head>\n<body>\n  <noscript>\n    <strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>\n  </noscript>\n  <div id=\"app\"></div>\n  <!-- built files will be auto injected -->\n</body>\n</html>"
        },
        {
          "type": "file",
          "path": "public/manifest.json",
          "content": "{\n  \"name\": \"Vue PWA\",\n  \"short_name\": \"VuePWA\",\n  \"start_url\": \"/\",\n  \"display\": \"standalone\",\n  \"background_color\": \"#ffffff\",\n  \"theme_color\": \"#4DBA87\",\n  \"icons\": [\n    {\n      \"src\": \"/icons/icon-192x192.png\",\n      \"sizes\": \"192x192\",\n      \"type\": \"image/png\"\n    },\n    {\n      \"src\": \"/icons/icon-512x512.png\",\n      \"sizes\": \"512x512\",\n      \"type\": \"image/png\"\n    }\n  ]\n}"
        }
      ]
    },
    {
      "name": "Ensure Accessibility and SEO",
      "description": "Follow best practices to make the PWA accessible and optimized for search engines.",
      "actions": [
        {
          "type": "file",
          "path": "src/App.vue",
          "content": "<template>\n  <div id=\"app\">\n    <nav>\n      <router-link to=\"/\">Home</router-link>\n      <router-link to=\"/about\">About</router-link>\n    </nav>\n    <router-view/>\n  </div>\n</template>\n<script>\nexport default {\n  name: 'App'\n}\n</script>\n<style>\nnav {\n  padding: 1em;\n  background-color: #4DBA87;\n}\nnav a {\n  margin-right: 1em;\n  color: white;\n  text-decoration: none;\n}\n</style>"
        },
        {
          "type": "file",
          "path": "public/robots.txt",
          "content": "User-agent: *\nDisallow:"
        },
        {
          "type": "file",
          "path": "public/sitemap.xml",
          "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n  <url>\n    <loc>https://example.com/</loc>\n    <changefreq>daily</changefreq>\n    <priority>1.0</priority>\n  </url>\n  <url>\n    <loc>https://example.com/about</loc>\n    <changefreq>monthly</changefreq>\n    <priority>0.8</priority>\n  </url>\n</urlset>"
        }
      ]
    }
  ]
}