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>" } ] } ] }