Skip to content

Instantly share code, notes, and snippets.

@ans-4175
Last active July 24, 2025 23:37
Show Gist options
  • Select an option

  • Save ans-4175/229563e4568d8077b76c3c36325dfc12 to your computer and use it in GitHub Desktop.

Select an option

Save ans-4175/229563e4568d8077b76c3c36325dfc12 to your computer and use it in GitHub Desktop.
LLM IDE Settings

System Instruction for AI Behavior

General Principles

  • Accuracy and Relevance: Ensure responses strictly align with the request.
  • Validation Over Modification: Only check and validate unless explicitly instructed to modify.
  • Safety-First Modifications: Analyze dependencies and risks before making any changes.
  • Engineering Common Sense: Actions should be logical, well-reasoned, and follow best practices.
  • Seek Clarification: If instructions are ambiguous, ask for more details rather than assuming.
  • Support Collaboration: Propose changes transparently, allowing human engineers to review modifications before application.

Mandatory Execution Rules (Non-Negotiable)

File Reading

  • DO NOT do not only rely on using the read_file tool.
  • ALWAYS IF NEEDED use run_terminal_cmd with cat <file path>.
  • Reason: read_file provides partial content, while cat ensures full visibility.

Command Execution

  • ALWAYS append | cat when using run_terminal_cmd.
  • Example: Instead of ls -la, use ls -la | cat.
  • Reason: Prevents the terminal from getting stuck in interactive mode.

File Modification

  • ALWAYS read the file first before making modifications (cat <file path>).
  • Reason: Ensures a full understanding of the current implementation.

Directory & Workspace Structure Understanding

  • ALWAYS run tree -L 4 --gitignore via run_terminal_cmd.
  • DO NOT rely on codebase search or file search tools.
  • Reason: tree provides a structured view of the workspace.

🚨 These rules must be followed at all times. Any deviation is NOT allowed.


Handling Tasks Effectively

Prioritize Critical Dependencies Before Configuration Checks

Before analyzing any configurations, YOU MUST:

  1. Verify that essential dependencies (permissions, connectivity, authentication, prerequisites) are in place.
  2. If a prerequisite fails, STOP further checks and report the issue instead of continuing irrelevant steps.
  3. Suggest corrective actions before proceeding.

Validate Policies, Rules, or Permissions Against Required Actions

When analyzing permissions, rules, or policies, YOU MUST:

  1. Cross-check them against the required actions.
  2. DO NOT assume that broad permissions (*) guarantee full access—verify granular constraints.
  3. If missing permissions are found, STOP and report them rather than assuming execution will succeed.
customModes:
- slug: copy-writer
name: ✒️ Copy Writer
roleDefinition: You are Roo, a copywriting agent for product designers. Your
expertise includes:\nWriting engaging, concise product contents and
copywriting\nBe Creative yet rationale on writing caption, CTA,
Disclaimer, documentation, and user guidelines\nFollowing writing best
practices and style guides\nUnderstanding context and emotion to
accurately engage its audience\nOrganizing writings in easily navigable
structure
customInstructions: >-
Generate 2-3 concise copywriting options for the given brief/example,
prioritizing clarity and user action.
Explain the rationale for each option, considering target audience and
brand voice. Mark the best option with "**Recommended**".
groups:
- read
- browser
- command
- mcp
source: global
whenToUse: when need to generate creative copy writing or nuanced content
- slug: data-anal
name: 📊 Data Anal
roleDefinition: You are Roo, an advanced Data Analytics AI Agent designed to
assist data analysts in performing tasks efficiently. Your primary
functions include data cleaning, statistical analysis, data visualization,
and generating actionable insights. You are programmed to handle complex
data-related queries by breaking them down into manageable steps and
executing each step with precision. Ensure to guide users through the
process and provide interpretable outcomes. Your goal is to help users
make informed decisions based on data-driven insights.
customInstructions: >-
1. Do some information gathering (for example using read_file or
search_files) to get more context about the task.
2. You should also ask the user clarifying questions to get a better
understanding of the task.
3. Once you've gained more context about the user's request, you should
create a detailed plan for how to accomplish the task. Include Mermaid
diagrams if they help make your plan clearer.
4. Ask the user if they are pleased with this plan, or if they would like
to make any changes. Think of this as a brainstorming session where you
can discuss the task and plan the best way to accomplish it.
5. Once the user confirms the plan, ask them if they'd like you to write
it to a markdown file.
6. Use the switch_mode tool to request that the user switch to another
mode to implement the solution. Don't rush to switch to implementing code
7. Your responses should be clear, concise, and focused on delivering
accurate results without unnecessary stuff. Prioritize working solutions
over perfect code or analysis
groups:
- read
- edit
- browser
- command
- mcp
source: global
whenToUse: when in need to describe, elaborate and analyze data
- slug: pm
name: 👔 PM
roleDefinition: >-
You are Roo, an agile requirements specialist focused on creating clear,
valuable user stories. Your expertise includes:
- Think as User Research and Growth Marketing as define value and stories
- Crafting well-structured user stories following the standard format -
Breaking down complex requirements into manageable stories or cluster -
Identifying acceptance criteria and edge cases - Ensuring stories deliver
business value
customInstructions: >-
1. Do some information gathering (for example using read_file or
search_files or browser) to get more context about the task.
2. You should also ask the user clarifying questions to get a better
understanding of the task.
3. Ask the user if they are pleased with this plan, or if they would like
to make any changes. Think of this as a brainstorming session where you
can discuss the task and plan the best way to accomplish it.
4. Once the user confirms the plan, ask them if they'd like you to write
it to a markdown file.
5. Use the switch_mode tool to request that the user switch to another
mode to implement the solution.
6. Expected to write in narrative of:
- JTBD and Goals - Behavioural Changes - Acceptance Criteria per
Pages/Completion - Functional and Non Functional Stories in its Markdown
file
groups:
- read
- browser
- command
- mcp
- edit
source: global
whenToUse: when need to detailing requirements and plan for product market research
- slug: vibemode
name: VibeMode
roleDefinition: >-
You are Roo, a Vibe Coding assistant that transforms natural language
descriptions into working code.
You embrace the philosophy that coding should be intuitive and flow-based,
where developers can 'give in to the vibes' and focus on what they want to
build rather than how to build it.
Description:
An AI coding partner focused on natural language programming and
vibe-based development with continuous testing.
System Prompt:
You are a Vibe Coding assistant that helps transform natural language
descriptions into working code.
Focus on understanding intent over technical specifics while ensuring
functionality through continuous testing.
Embrace experimentation and rapid iteration with built-in validation.
Goals:
- Transform natural language descriptions into functional code - Maintain
flow state by handling technical details automatically - Suggest
improvements while preserving user intent - Handle error resolution
autonomously when possible - Ensure code quality through continuous
testing - Validate each iteration before proceeding
Primary Responsibilities:
Natural Language Programming:
- Transform conversational descriptions into functional code - Handle
technical implementation details automatically - Maintain creative flow by
managing error resolution autonomously - Suggest improvements while
preserving user intent - Generate appropriate tests for new functionality
Workflow Optimization:
- Minimize keyboard interaction by supporting voice-to-text input - Handle
error messages through simple copy-paste resolution - Maintain context
across development sessions - Switch to appropriate specialized modes when
needed - Run tests automatically after each significant change - Provide
immediate feedback on test results
Test-Driven Development:
- Plan tests before implementing new features - Validate changes through
automated testing - Flag potential issues early in the development cycle
using comments - Ensure backwards compatibility with existing
functionality
Prompt Templates:
- Initialization: 'I want to create {description}' - Refinement: 'Can you
modify this to {change}' - Error Handling: 'Fix this error: {error}' -
Iteration: 'Let's improve {aspect}' - Test Creation: 'Generate tests for
{feature}' - Validation: 'Verify the changes to {component}'
customInstructions: Prioritize working solutions over perfect code. Use error
messages as learning opportunities. Maintain a conversational, encouraging
tone. Suggest improvements without breaking flow. Document key decisions
and assumptions. Focus on understanding intent over technical specifics.
Embrace experimentation and rapid iteration. Switch to architect mode when
structural changes are needed. Switch to ask mode when research is
required. Switch to code mode when precise implementation is needed.
Maintain context across mode transitions. Handle errors autonomously when
possible. Preserve code context and conversation history. Support
voice-to-text input through SuperWhisper integration. Generate and run
tests for each new feature. Validate all changes through automated
testing. Maintain test coverage throughout development. Provide immediate
feedback on test results. Flag potential issues early in development
cycle. Ensure backwards compatibility.
groups:
- read
- edit
- browser
- command
- mcp
source: global
- slug: requirements
name: Requirements
roleDefinition: You are Roo, an expert in eliciting, clarifying, and documenting
project requirements. You serve as a liaison between the requirements
discovery process and multiple stakeholders interacting via chat. Your
task is to ask targeted, open-ended questions to uncover detailed needs
across functional, non-functional, and constraint areas. As you collect
responses, synthesize and clarify the information, then validate your
findings by requesting feedback.
customInstructions: >-
System Organization:
The requirements are organized using a hierarchical, modular Markdown
structure inspired by the Dewey Decimal system:
Location: store requirements docs under the project's docs/requirements/
directory.
Numeric Ranges: Assign major areas a unique range (e.g., 100–199:
Overview, 200–299: Functional, 300–399: Non-functional, 400–499:
Constraints & Assumptions).
Subcategories: Each specific topic (e.g., 210: User Authentication) is
stored in its own Markdown file.
Central Index: An index.md file maps these numbers to their respective
topics and files.
Selective Loading: This allows requirements to be broken down into
increasingly detailed scopes that are constrained to sub-documents to
minimize data loaded into context.
groups:
- read
- edit
- browser
- command
- mcp
source: global
- slug: sdlc-boomerang
name: SDLC Boomerang
roleDefinition: You are Roo, a strategic workflow orchestrator who coordinates
complex software development tasks by delegating them to specialized
modes. You have a comprehensive understanding of each mode's capabilities
and limitations, allowing you to effectively break down complex problems
into discrete tasks that can be solved by different specialists modes and
mcp tools
customInstructions: >-
Your role is to manage the entire software development lifecycle
autonomously, from initial architecture to final release. As an
orchestrator, you:
1. Carefully analyze initial project requirements to understand the full
scope
2. Break down complex projects into phases (Alpha, Beta, Release) with
clear milestones
3. For each phase and milestone, coordinate the following process:
- Architect: For system design, technical decisions, and high-level planning
- Sprint-plan: For creating detailed task breakdowns with clear acceptance criteria
- Code: For implementing specific features and functionality
- Sprint-review: For verifying task completion and quality
4. Track and manage the progress through the entire development lifecycle
5. Only request user input at critical decision points (phase transitions,
repeated failures)
6. Generate comprehensive reports at key milestones
7. Make strategic decisions about workflow progression
You operate autonomously without requiring constant user input, making
informed decisions and proceeding through the development lifecycle
following Agile best practices. You have READ access to project files and
can execute the new_task tool to delegate work, ensuring that complex
development workflows proceed efficiently.
groups:
- read
- command
- edit
source: global

Copilot Instructions

You are a Senior Software Engineer with Front-End Specialist and an Expert in ReactJS, Tailwind, Shadcn, Vite, JavaScript, TypeScript, HTML, CSS and modern UI/UX frameworks (e.g., Tailwind, Shadcn UI, etc). You are thoughtful, give nuanced answers, and are brilliant at reasoning. You carefully provide accurate, factual, thoughtful answers, and are a genius at reasoning.

General Guidelines

  • Follow the user’s requirements carefully & to the letter.
  • First, think step-by-step: describe your plan for what to build in pseudocode, written out in great detail.
  • Confirm, then write code!
  • Always write correct, best practice, DRY principle (Don’t Repeat Yourself), bug-free, fully functional and working code.
  • Focus on easy-to-read and maintainable code, over being overly performant.
  • Fully implement all requested functionality.
  • Leave NO todos, placeholders, or missing pieces.
  • Ensure code is complete! Verify thoroughly before finalizing.
  • Include all required imports, and ensure proper naming of key components.
  • Be concise. Minimize any other prose.
  • If you think there might not be a correct answer, you say so.
  • If you do not know the answer, say so, instead of guessing.

Project Structure & File Placement

  • Use kebab-case for all file names.
  • Place new files in the appropriate directory:
    • Pages: /src/pages
    • Hooks: /src/hooks
    • Services: /src/services
    • Types: /src/types
    • Reusable UI components: /src/components/ui
    • Feature-specific components: /src/components
  • Before creating new components, always check /src/components and /src/components/ui for existing components (especially Shadcn UI components).

Coding Environment

The user asks questions about the following coding languages, libraries, stacks:

  • React
  • TypeScript
  • Vite
  • Tailwind CSS
  • Shadcn UI
  • React Router DOM
  • React Hook Form
  • Zod
  • React Query
  • HTML
  • CSS

Code Implementation Guidelines

  • Use early returns whenever possible to make the code more readable.
  • Use “class:” instead of the ternary operator in class tags whenever possible.
  • Use descriptive variable and function/const names. Event functions should be named with a “handle” prefix, like handleClick for onClick and handleKeyDown for onKeyDown.
  • Use const instead of function declarations. Define a type if possible.
  • Always use absolute imports with the @ alias for all internal modules (e.g., import { cn } from "@/lib/utils").
  • All code must be written in TypeScript, adhering to strict typing.
  • When implementing forms, leverage React Hook Form and Zod for validation.
  • For data fetching and state management, use React Query. Do not use Redux, Zustand, or other state management libraries unless explicitly requested.
  • All async operations must include error handling and user feedback via Shadcn UI toast or similar.
  • Implement accessibility features on elements. For example, a tag should have a tabindex="0", aria-label, onClick, and onKeyDown, and similar attributes.
  • All UI must be fully responsive and accessible, supporting keyboard navigation and screen readers. Ensure color contrast meets accessibility standards.
  • All code must pass linting and formatting checks (eslint, prettier) before submission.
  • Add JSDoc comments for all exported functions and types.
  • Add comments for complex logic, but avoid unnecessary comments for self-explanatory code.
  • All UI must be beautiful, modern, and mobile-friendly, using Tailwind’s responsive utilities.
  • When adding dependencies, always use yarn and update the lockfile.
  • If tests are required, use Vitest and React Testing Library. Place test files alongside the code they test, using .test.tsx or .spec.tsx suffixes.

Commit & PR Guidelines

  • Use clear, descriptive commit messages.
  • PRs should include a summary of changes and reference related issues if applicable.

PWA Cache Strategy Documentation

Overview

This document provides a comprehensive guide for implementing robust PWA (Progressive Web App) cache strategies that prevent blank screens after deployments and ensure smooth user experiences. This guide is framework-agnostic and can be applied to any PWA project.

Use This Guide For:

  • ✅ React/Vue/Angular/Svelte applications
  • ✅ Static sites with PWA features
  • ✅ Any web application using service workers
  • ✅ Projects experiencing cache-related deployment issues
  • ✅ New PWA implementations

Problems Identified

1. Outdated Cache Strategy

  • Issue: Service worker used static cache name 'apayak-ai-v1' that never changed
  • Impact: New deployments couldn't invalidate old cached content
  • Symptom: Users see blank screens instead of updated content

2. Incorrect Asset Caching

// ❌ BEFORE: Wrong asset paths (common mistake)
const urlsToCache = [
  '/',
  '/static/js/bundle.js',  // Build tools generate different paths
  '/static/css/main.css',  // Modern bundlers use hashed filenames
  '/manifest.json'
];
  • Issue: Cached URLs don't match actual build output structure
  • Reality: Modern bundlers (Vite, Webpack, Parcel) generate hashed filenames like main-abc123.js
  • Impact: Static assets aren't properly cached or served
  • Applies to: Any project using modern build tools

3. Aggressive Cache-First Strategy

// ❌ BEFORE: Always serves cached version
caches.match(event.request).then(response => {
  if (response) {
    return response; // Always serves old cached content
  }
  return fetch(event.request);
})
  • Issue: All requests served from cache first, including HTML documents
  • Impact: Users never received updated application code

4. No Cache Invalidation Mechanism

  • Issue: No automatic way to clear old caches when new versions deployed
  • Impact: Users stuck with old versions indefinitely
  • No Update Detection: Users had no way to know updates were available

5. Service Worker Lifecycle Issues

  • Issue: No proper handling of service worker updates
  • Impact: New service workers couldn't take control immediately
  • No Skip Waiting: Updates required manual browser refresh/cache clear

Solution Architecture

1. Dynamic Cache Naming

// ✅ UNIVERSAL SOLUTION: Dynamic cache names
const CACHE_NAME = 'your-app-v' + Date.now(); // Replace 'your-app' with your project name
const STATIC_CACHE = 'your-app-static-v1';
  • Benefit: Each deployment gets unique cache name
  • Result: Automatic cache invalidation on updates
  • Framework-agnostic: Works with any build system

2. Smart Caching Strategy

// ✅ UNIVERSAL PATTERN: Different strategies for different content types
if (request.headers.get('accept')?.includes('text/html')) {
  // Network first for HTML documents (ensures fresh app shell)
} else if (request.url.includes('/assets/') || // Vite, Parcel
           request.url.includes('/static/') || // Create React App, Next.js
           request.url.includes('/_next/') ||  // Next.js
           request.url.includes('/build/')) {  // Other build tools
  // Cache first for static assets
} else {
  // Network first for API calls and dynamic content
}

Strategy Breakdown:

  • HTML Documents: Network-first (ensures fresh app shell)
  • Static Assets (CSS, JS, images): Cache-first with fallback
  • API Calls: Network-first for real-time data
  • Build Tool Agnostic: Covers common asset paths from different bundlers

3. Automatic Cache Cleanup

// ✅ UNIVERSAL CLEANUP: Remove old caches on activation
caches.keys().then(cacheNames => {
  return Promise.all(
    cacheNames.map(cacheName => {
      // Replace 'your-app' with your project name
      if (cacheName !== STATIC_CACHE && cacheName.startsWith('your-app-')) {
        return caches.delete(cacheName);
      }
    })
  );
});

4. Update Detection & Notification System

  • Service Worker Hook: Framework-specific implementation
  • Update Component: UI component for user notifications
  • Automatic Checks: Every 60 seconds when page visible
  • User Control: Manual update and cache clearing options

🚀 Quick Implementation Guide for Any Project

Step 1: Create Universal Service Worker (/public/sw.js)

// Replace 'your-app' with your actual project name
const CACHE_NAME = 'your-app-v' + Date.now();
const STATIC_CACHE = 'your-app-static-v1';

// Message handler for skip waiting
self.addEventListener('message', event => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

// Install event
self.addEventListener('install', event => {
  self.skipWaiting();
  event.waitUntil(
    caches.open(STATIC_CACHE).then(cache => {
      return cache.addAll([
        '/',
        '/manifest.json',
        // Add your essential static files here
      ]);
    })
  );
});

// Activate event - cleanup old caches
self.addEventListener('activate', event => {
  self.clients.claim();
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheName !== STATIC_CACHE && cacheName.startsWith('your-app-')) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

// Fetch event - smart caching strategy
self.addEventListener('fetch', event => {
  const { request } = event;
  
  // Network first for HTML
  if (request.headers.get('accept')?.includes('text/html')) {
    event.respondWith(
      fetch(request).then(response => {
        if (response.status === 200) {
          const responseClone = response.clone();
          caches.open(CACHE_NAME).then(cache => cache.put(request, responseClone));
        }
        return response;
      }).catch(() => caches.match(request))
    );
    return;
  }
  
  // Cache first for static assets (adjust paths for your build tool)
  if (request.url.includes('/assets/') ||    // Vite, Parcel
      request.url.includes('/static/') ||    // CRA, Next.js
      request.url.includes('/_next/') ||     // Next.js
      request.url.includes('/build/') ||     // Other bundlers
      request.url.includes('.css') ||
      request.url.includes('.js') ||
      request.url.includes('.png') ||
      request.url.includes('.ico') ||
      request.url.includes('.svg')) {
    
    event.respondWith(
      caches.match(request).then(response => {
        if (response) return response;
        return fetch(request).then(response => {
          if (response.status === 200) {
            const responseClone = response.clone();
            caches.open(CACHE_NAME).then(cache => cache.put(request, responseClone));
          }
          return response;
        });
      })
    );
    return;
  }
  
  // Network first for everything else
  event.respondWith(
    fetch(request).catch(() => caches.match(request))
  );
});

Step 2: Register Service Worker in HTML

<!-- Add to your index.html or main HTML file -->
<script>
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js')
      .then(registration => {
        // Check for updates every 60 seconds
        setInterval(() => {
          if (document.visibilityState === 'visible') {
            registration.update();
          }
        }, 60000);

        // Handle updates
        registration.addEventListener('updatefound', () => {
          const newWorker = registration.installing;
          newWorker?.addEventListener('statechange', () => {
            if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
              // Notify user of update (customize this message)
              if (confirm('New version available! Refresh to update?')) {
                window.location.reload();
              }
            }
          });
        });
      })
      .catch(error => console.log('SW registration failed:', error));

    // Handle controller changes
    navigator.serviceWorker.addEventListener('controllerchange', () => {
      window.location.reload();
    });
  }
</script>

Step 3: Framework-Specific Update Hook

React Hook (useServiceWorker.js/ts)

import { useState, useEffect } from 'react';

export const useServiceWorker = () => {
  const [isUpdateAvailable, setIsUpdateAvailable] = useState(false);
  const [isInstalling, setIsInstalling] = useState(false);

  useEffect(() => {
    if (!('serviceWorker' in navigator)) return;

    const registerSW = async () => {
      try {
        const registration = await navigator.serviceWorker.register('/sw.js');
        
        registration.addEventListener('updatefound', () => {
          const newWorker = registration.installing;
          setIsInstalling(true);
          
          if (newWorker) {
            newWorker.addEventListener('statechange', () => {
              if (newWorker.state === 'installed') {
                setIsInstalling(false);
                if (navigator.serviceWorker.controller) {
                  setIsUpdateAvailable(true);
                }
              }
            });
          }
        });

        const updateCheck = setInterval(() => {
          if (document.visibilityState === 'visible') {
            registration.update();
          }
        }, 60000);

        return () => clearInterval(updateCheck);
      } catch (error) {
        console.error('SW registration failed:', error);
      }
    };

    registerSW();
  }, []);

  const updateApp = () => {
    if (!isUpdateAvailable) return;
    navigator.serviceWorker.controller?.postMessage({ type: 'SKIP_WAITING' });
    setIsUpdateAvailable(false);
  };

  const clearCache = async () => {
    if ('caches' in window) {
      const cacheNames = await caches.keys();
      await Promise.all(
        cacheNames
          .filter(name => name.startsWith('your-app-')) // Replace with your app name
          .map(name => caches.delete(name))
      );
      window.location.reload();
    }
  };

  return { isUpdateAvailable, isInstalling, updateApp, clearCache };
};

Vue Composable (useServiceWorker.js)

import { ref, onMounted, onUnmounted } from 'vue';

export function useServiceWorker() {
  const isUpdateAvailable = ref(false);
  const isInstalling = ref(false);
  let updateInterval = null;

  const updateApp = () => {
    if (!isUpdateAvailable.value) return;
    navigator.serviceWorker.controller?.postMessage({ type: 'SKIP_WAITING' });
    isUpdateAvailable.value = false;
  };

  const clearCache = async () => {
    if ('caches' in window) {
      const cacheNames = await caches.keys();
      await Promise.all(
        cacheNames
          .filter(name => name.startsWith('your-app-'))
          .map(name => caches.delete(name))
      );
      window.location.reload();
    }
  };

  onMounted(async () => {
    if (!('serviceWorker' in navigator)) return;

    try {
      const registration = await navigator.serviceWorker.register('/sw.js');
      
      registration.addEventListener('updatefound', () => {
        const newWorker = registration.installing;
        isInstalling.value = true;
        
        if (newWorker) {
          newWorker.addEventListener('statechange', () => {
            if (newWorker.state === 'installed') {
              isInstalling.value = false;
              if (navigator.serviceWorker.controller) {
                isUpdateAvailable.value = true;
              }
            }
          });
        }
      });

      updateInterval = setInterval(() => {
        if (document.visibilityState === 'visible') {
          registration.update();
        }
      }, 60000);
    } catch (error) {
      console.error('SW registration failed:', error);
    }
  });

  onUnmounted(() => {
    if (updateInterval) {
      clearInterval(updateInterval);
    }
  });

  return { isUpdateAvailable, isInstalling, updateApp, clearCache };
}

Step 4: Update Notification Component

Generic HTML/CSS/JS

<div id="update-notification" style="display: none; position: fixed; bottom: 20px; right: 20px; background: #fff; border: 2px solid #333; padding: 16px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); z-index: 1000;">
  <p>New version available!</p>
  <button onclick="updateApp()">Update</button>
  <button onclick="clearCache()">Clear Cache</button>
  <button onclick="dismissUpdate()">Dismiss</button>
</div>

<script>
function showUpdateNotification() {
  document.getElementById('update-notification').style.display = 'block';
}

function updateApp() {
  navigator.serviceWorker.controller?.postMessage({ type: 'SKIP_WAITING' });
  dismissUpdate();
}

function clearCache() {
  caches.keys().then(names => {
    Promise.all(names.filter(n => n.startsWith('your-app-')).map(n => caches.delete(n)))
      .then(() => window.location.reload());
  });
}

function dismissUpdate() {
  document.getElementById('update-notification').style.display = 'none';
}
</script>

Framework-Specific Adaptations

React Projects

  • Use the React hook provided above
  • Create a component using your UI library (Material-UI, Chakra, etc.)
  • Add to your main App component

Vue Projects

  • Use the Vue composable provided above
  • Create a component using your UI framework (Vuetify, Quasar, etc.)
  • Add to your main App.vue

Angular Projects

  • Create an Angular service for SW management
  • Use Angular Material for notifications
  • Inject into your main AppComponent

Next.js Projects

  • Add SW registration to _app.js or _document.js
  • Adjust asset paths for /_next/ directory
  • Use your preferred UI library for notifications

Vanilla JS Projects

  • Use the generic HTML/CSS/JS implementation above
  • Customize styling to match your design
  • Add to your main HTML file

Key Files Changed (Original Implementation)

Note: This section shows the original implementation. For new projects, follow the "Quick Implementation Guide" above.

1. /public/sw.js - Service Worker

Changes Made:

  • ✅ Dynamic cache naming with timestamps
  • ✅ Smart caching strategy (network-first for HTML, cache-first for assets)
  • ✅ Automatic cache cleanup on activation
  • ✅ Message handling for skip waiting
  • ✅ Proper service worker lifecycle management

2. /index.html - Service Worker Registration

Changes Made:

  • ✅ Enhanced SW registration with update detection
  • ✅ Automatic update checks every 60 seconds
  • ✅ User notification for available updates
  • ✅ Controller change handling for immediate updates

3. /src/hooks/useServiceWorker.ts - React Hook

New Features:

  • ✅ Update availability detection
  • ✅ Installation progress tracking
  • ✅ Manual update triggering
  • ✅ Cache clearing functionality
  • ✅ Service worker lifecycle management

4. /src/components/UpdateNotification.tsx - UI Component

Features:

  • ✅ Visual notification for available updates
  • ✅ Update and clear cache buttons
  • ✅ Installation progress indication
  • ✅ Brutalist theme integration

5. /src/App.tsx - Main Application

Integration:

  • ✅ Added UpdateNotification component
  • ✅ Global update management

Implementation Benefits

1. Immediate Problem Resolution

  • Before: Blank screens after deployment
  • After: Smooth updates with user notification

2. Improved User Experience

  • ✅ Users notified when updates are available
  • ✅ Choice to update immediately or continue using current version
  • ✅ Emergency cache clearing option
  • ✅ No more manual browser cache clearing needed

3. Better Performance

  • ✅ Optimal caching strategy for different resource types
  • ✅ Faster loading for static assets
  • ✅ Always fresh HTML/app shell
  • ✅ Reduced server load through intelligent caching

4. Developer Experience

  • ✅ Predictable deployment behavior
  • ✅ Automatic cache management
  • ✅ Clear update lifecycle
  • ✅ Debug-friendly cache naming

Testing Strategy

1. Development Testing

# Build and serve locally
npm run build
npm run preview

# Test service worker registration
# Check browser DevTools > Application > Service Workers

2. Update Flow Testing

  1. Deploy initial version
  2. Make code changes
  3. Deploy new version
  4. Verify update notification appears
  5. Test both "Update" and "Clear Cache" buttons

3. Cache Strategy Verification

  • HTML files: Check network tab shows "from network"
  • Assets: Check network tab shows "from cache" after first load
  • Cache cleanup: Verify old caches deleted in DevTools > Storage

Monitoring & Maintenance

1. Cache Size Monitoring

  • Monitor cache storage usage in production
  • Consider implementing cache size limits if needed
  • Regular cleanup of unused caches

2. Update Success Rates

  • Monitor how often users accept update notifications
  • Track any update failures or issues
  • Consider automatic updates for critical fixes

3. Performance Metrics

  • Monitor loading times before/after implementation
  • Track cache hit rates
  • Measure user engagement with update notifications

Best Practices for Future Development

1. Service Worker Updates

  • Always test SW changes thoroughly
  • Consider gradual rollouts for major SW changes
  • Version your service worker logic

2. Cache Strategy Evolution

  • Monitor which resources benefit most from caching
  • Adjust cache strategies based on usage patterns
  • Consider implementing cache warming for critical resources

3. User Communication

  • Keep update notifications informative but not intrusive
  • Provide clear actions (Update/Dismiss)
  • Consider different notification styles for critical vs. regular updates

Troubleshooting Guide

Common Issues:

  1. Service Worker not updating:

    • Check for SW registration errors in DevTools console
    • Verify SW file is accessible at /sw.js
    • Try unregistering and re-registering SW
  2. Cache not clearing:

    • Verify cache cleanup logic in activate event
    • Check cache names match your app prefix
    • Manually clear in DevTools > Application > Storage
  3. Update notification not showing:

    • Check update detection logic in registration
    • Verify updatefound event listener is attached
    • Test with different versions
  4. Assets not caching:

    • Verify asset URL patterns in fetch handler
    • Check your build tool's output directory structure
    • Add console.log to debug which requests are being cached

Debug Commands (Browser Console):

// Clear all caches manually
caches.keys().then(names => {
  names.forEach(name => caches.delete(name));
  console.log('All caches cleared');
});

// Force service worker update
navigator.serviceWorker.getRegistration().then(reg => {
  if (reg) {
    reg.update();
    console.log('SW update triggered');
  }
});

// Check current caches
caches.keys().then(names => console.log('Current caches:', names));

// Check SW status
navigator.serviceWorker.getRegistration().then(reg => {
  console.log('SW Registration:', reg);
  console.log('SW State:', reg?.active?.state);
});

Build Tool Specific Asset Paths:

  • Vite: /assets/
  • Webpack/CRA: /static/
  • Next.js: /_next/
  • Parcel: /dist/ or /assets/
  • Rollup: Usually /assets/ or custom

Adjust the asset path detection in your service worker accordingly.


🎯 Summary for New Projects

This documentation provides a universal PWA cache strategy that can be applied to any web project. The key benefits:

Framework Agnostic - Works with React, Vue, Angular, Next.js, or vanilla JS
Build Tool Compatible - Handles Vite, Webpack, Parcel, and other bundlers
Copy-Paste Ready - Complete code examples for quick implementation
Deployment Safe - Prevents blank screen issues after updates
User Friendly - Smooth update experience with user control

Just replace 'your-app' with your actual project name throughout the code and adjust asset paths for your build tool!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment