Skip to content
Back to skills

Configure Cache Busting

ASecurity

Check and configure cache-busting strategies for Next.js and Vite projects

  • 58 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added February 8, 2026
developmentjavascripttypescriptgojavabashreactvuenextjsnodedocker

Works with

  • cli
  • api

Security analysis

A96/100
  • mediumUses curl or wget to download content

Pro shows the line behind each finding and how to fix it

Scanned February 12, 2026

npx -y skills add laurigates/claude-plugins --skill configure-cache-busting --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Configure Cache Busting?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Configure Cache Busting
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/laurigates-configure-cache-busting/badge)](https://www.skillsdirectory.com/skills/laurigates-configure-cache-busting)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
model: haiku
created: 2025-12-16
modified: 2026-02-05
reviewed: 2025-12-16
description: Check and configure cache-busting strategies for Next.js and Vite projects
allowed-tools: Glob, Grep, Read, Write, Edit, Bash, AskUserQuestion, TodoWrite
argument-hint: "[--check-only] [--fix] [--framework <nextjs|vite>] [--cdn <cloudflare|vercel|none>]"
name: configure-cache-busting
---

## Context

- Project root: !`pwd`
- Package files: !`find . -maxdepth 1 -name 'package.json' 2>/dev/null`
- Next.js config: !`find . -maxdepth 1 -name 'next.config.*' 2>/dev/null`
- Vite config: !`find . -maxdepth 1 -name 'vite.config.*' 2>/dev/null`
- Build output: !`find . -maxdepth 1 -type d \( -name '.next' -o -name 'dist' -o -name 'out' \) 2>/dev/null`
- CDN config: !`find . -maxdepth 1 \( -name 'vercel.json' -o -name '_headers' -o -name '_redirects' \) 2>/dev/null && find public -maxdepth 1 -name '_headers' 2>/dev/null`
- Project standards: !`find . -maxdepth 1 -name '.project-standards.yaml' 2>/dev/null`

## Parameters

Parse from command arguments:

- `--check-only`: Report compliance status without modifications (CI/CD mode)
- `--fix`: Apply fixes automatically without prompting
- `--framework <nextjs|vite>`: Override framework detection
- `--cdn <cloudflare|vercel|none>`: Specify CDN provider for cache header configuration

## Your Task

Configure production-ready cache-busting strategies for Next.js or Vite projects.

### Phase 1: Framework Detection

Detect project framework from file structure:

| Indicator | Framework | Config File |
|-----------|-----------|-------------|
| `next.config.js` or `next.config.mjs` | Next.js | `next.config.*` |
| `next.config.ts` | Next.js | `next.config.ts` |
| `vite.config.js` or `vite.config.ts` | Vite | `vite.config.*` |
| `.next/` directory | Next.js (built) | Detection only |
| `dist/` directory + vite in package.json | Vite (built) | Detection only |

**Check package.json dependencies:**
- Next.js: `"next": "^14.0.0"` or similar
- Vite: `"vite": "^5.0.0"` or similar

**If both detected:**
```
Multiple frameworks detected. Please specify with --framework:
  --framework nextjs
  --framework vite
```

**If neither detected:**
```
No supported framework detected.

This command supports:
  - Next.js (next.config.js/ts)
  - Vite (vite.config.js/ts)

Would you like to:
  [A] Specify framework manually (--framework <nextjs|vite>)
  [B] Exit - wrong project type
```

### Phase 2: Current State Analysis

For the detected framework, analyze existing cache-busting configuration:

#### Next.js Analysis

**Check `next.config.js/ts`:**
- [ ] `output: 'export'` or `output: 'standalone'` specified
- [ ] `generateBuildId` configured for deterministic builds
- [ ] `assetPrefix` configured for CDN
- [ ] `compress: true` enabled
- [ ] `poweredByHeader: false` for security
- [ ] `generateEtags` configured

**Check `public/` directory:**
- [ ] Static assets present
- [ ] Cache headers configured (Vercel: `vercel.json`, Cloudflare: `_headers`)

**Check build output (if `.next/` exists):**
- [ ] Static assets have content hashes in filenames
- [ ] Build ID is consistent/deterministic
- [ ] Manifest files generated

#### Vite Analysis

**Check `vite.config.js/ts`:**
- [ ] `build.rollupOptions.output.entryFileNames` configured with `[hash]`
- [ ] `build.rollupOptions.output.chunkFileNames` configured with `[hash]`
- [ ] `build.rollupOptions.output.assetFileNames` configured with `[hash]`
- [ ] `build.manifest: true` for SSR/manifest-based routing
- [ ] `build.cssCodeSplit` configured appropriately
- [ ] `build.sourcemap` set for production debugging

**Check `public/` directory:**
- [ ] Static assets present (copied without hashing)
- [ ] Cache headers configured

**Check build output (if `dist/` exists):**
- [ ] Assets have content hashes: `app.[hash].js`
- [ ] CSS files have hashes: `style.[hash].css`
- [ ] Manifest file generated (if configured)

### Phase 3: CDN Provider Detection

Detect CDN provider from project configuration:

| Indicator | CDN Provider |
|-----------|--------------|
| `vercel.json` exists | Vercel |
| `.vercelignore` exists | Vercel |
| `_headers` in root or `public/` | Cloudflare Pages |
| `_redirects` exists | Cloudflare Pages / Netlify |
| `wrangler.toml` exists | Cloudflare Workers/Pages |
| None of the above | Generic / None |

### Phase 4: Compliance Report

```
Cache-Busting Compliance Report
================================
Project: [name]
Framework: [Next.js 14.x | Vite 5.x]
CDN Provider: [Vercel | Cloudflare | None detected]

Framework Configuration:
  Config file             next.config.js              [✅ EXISTS | ❌ MISSING]
  Asset hashing           [hash] in filenames         [✅ ENABLED | ❌ DISABLED]
  Build manifest          manifest files              [✅ GENERATED | ❌ MISSING]
  Deterministic builds    Build ID configured         [✅ PASS | ⚠️ NOT SET]
  Compression             gzip/brotli enabled         [✅ PASS | ⚠️ DISABLED]

Cache Headers:
  Static assets           immutable, 1y               [✅ CONFIGURED | ❌ MISSING]
  HTML files              no-cache, must-revalidate   [✅ CONFIGURED | ❌ MISSING]
  API routes              varies by route             [✅ CONFIGURED | ⏭️ N/A]
  CDN configuration       vercel.json/_headers        [✅ EXISTS | ❌ MISSING]

Build Output (if built):
  Hashed filenames        app.[hash].js               [✅ DETECTED | ❌ NOT BUILT]
  Content addressing      Unique hashes per version   [✅ PASS | ⚠️ DUPLICATE]
  Manifest integrity      Valid manifest.json         [✅ PASS | ❌ INVALID]

Overall: [X issues found]

Recommendations:
  [List specific fixes needed]
```

### Phase 5: Configuration (if --fix or user confirms)

#### Next.js Configuration

**Create or update `next.config.js`:**
```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
  // Output mode for static export or standalone
  // output: 'export', // For static sites (GitHub Pages, S3, etc.)
  // output: 'standalone', // For Docker/containerized deployments

  // Deterministic build IDs for reproducible builds
  generateBuildId: async () => {
    // Use git commit SHA for deterministic builds
    return process.env.GIT_COMMIT_SHA || process.env.VERCEL_GIT_COMMIT_SHA || 'development';
  },

  // CDN asset prefix (optional)
  // assetPrefix: process.env.CDN_URL || '',

  // Enable compression
  compress: true,

  // Remove X-Powered-By header for security
  poweredByHeader: false,

  // Configure ETags for caching
  generateEtags: true,

  // Image optimization
  images: {
    // For static export, use unoptimized images
    // unoptimized: true,

    // Or configure image CDN
    domains: ['your-cdn-domain.com'],
    formats: ['image/avif', 'image/webp'],
  },

  // Headers for cache control
  async headers() {
    return [
      {
        // Static assets with content hashes - long-term cache
        source: '/_next/static/:path*',
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=31536000, immutable',
          },
        ],
      },
      {
        // Images - moderate caching
        source: '/_next/image/:path*',
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=86400, s-maxage=31536000, stale-while-revalidate',
          },
        ],
      },
      {
        // HTML pages - no cache, always revalidate
        source: '/:path*.html',
        headers: [
          {
            key: 'Cache-Control',
            value: 'public, max-age=0, must-revalidate',
          },
        ],
      },
      {
        // API routes - no cache by default
        source: '/api/:path*',
        headers: [
          {
            key: 'Cache-Control',
            value: 'no-store, no-cache, must-revalidate',
          },
        ],
      },
    ];
  },

  // Webpack configuration for additional control
  webpack: (config, { isServer }) => {
    // Ensure deterministic module IDs
    config.optimization = {
      ...config.optimization,
      moduleIds: 'deterministic',
    };

    return config;
  },
};

module.exports = nextConfig;
```

**Alternative TypeScript configuration (`next.config.ts`):**
```typescript
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  // Same configuration as above, but with TypeScript types
  generateBuildId: async () => {
    return process.env.GIT_COMMIT_SHA || process.env.VERCEL_GIT_COMMIT_SHA || 'development';
  },

  compress: true,
  poweredByHeader: false,
  generateEtags: true,

  async headers() {
    return [
      {
        source: '/_next/static/:path*',
        headers: [
          { key: 'Cache-Control', value: 'public, max-age=31536000, immutable' },
        ],
      },
      {
        source: '/:path*.html',
        headers: [
          { key: 'Cache-Control', value: 'public, max-age=0, must-revalidate' },
        ],
      },
    ];
  },
};

export default nextConfig;
```

#### Vite Configuration

**Create or update `vite.config.js`:**
```javascript
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue'; // or @vitejs/plugin-react

export default defineConfig({
  plugins: [vue()],

  build: {
    // Generate manifest for SSR or service workers
    manifest: true,

    // Enable CSS code splitting for better caching
    cssCodeSplit: true,

    // Source maps for production debugging (optional)
    sourcemap: false, // Set to 'hidden' for sentry integration

    // Rollup output options for cache busting
    rollupOptions: {
      output: {
        // JavaScript entry files with content hash
        entryFileNames: 'assets/[name].[hash].js',

        // JavaScript chunk files with content hash
        chunkFileNames: 'assets/[name].[hash].js',

        // CSS and other assets with content hash
        assetFileNames: (assetInfo) => {
          // Organize assets by type
          const info = assetInfo.name.split('.');
          const ext = info[info.length - 1];

          if (/\.(png|jpe?g|gif|svg|webp|avif)$/i.test(assetInfo.name)) {
            return 'assets/images/[name].[hash].[ext]';
          }

          if (/\.(woff2?|eot|ttf|otf)$/i.test(assetInfo.name)) {
            return 'assets/fonts/[name].[hash].[ext]';
          }

          if (/\.css$/i.test(assetInfo.name)) {
            return 'assets/css/[name].[hash].[ext]';
          }

          return 'assets/[name].[hash].[ext]';
        },

        // Manual chunk splitting for better caching
        manualChunks: (id) => {
          // Vendor chunks for stable caching
          if (id.includes('node_modules')) {
            // Split large vendor libraries
            if (id.includes('vue') || id.includes('react')) {
              return 'vendor-framework';
            }
            if (id.includes('lodash') || id.includes('moment')) {
              return 'vendor-utils';
            }
            return 'vendor';
          }
        },
      },
    },

    // Asset inline threshold (smaller assets inlined as base64)
    assetsInlineLimit: 4096, // 4KB

    // Chunk size warnings
    chunkSizeWarningLimit: 500, // KB
  },

  // Preview server headers (for local testing)
  preview: {
    headers: {
      'Cache-Control': 'public, max-age=600',
    },
  },
});
```

**Alternative TypeScript configuration (`vite.config.ts`):**
```typescript
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],

  build: {
    manifest: true,
    cssCodeSplit: true,
    sourcemap: false,

    rollupOptions: {
      output: {
        entryFileNames: 'assets/[name].[hash].js',
        chunkFileNames: 'assets/[name].[hash].js',
        assetFileNames: (assetInfo): string => {
          if (!assetInfo.name) return 'assets/[name].[hash][extname]';

          const ext = assetInfo.name.split('.').pop();
          if (/png|jpe?g|gif|svg|webp|avif/i.test(ext)) {
            return 'assets/images/[name].[hash][extname]';
          }
          if (/woff2?|eot|ttf|otf/i.test(ext)) {
            return 'assets/fonts/[name].[hash][extname]';
          }
          if (ext === 'css') {
            return 'assets/css/[name].[hash][extname]';
          }
          return 'assets/[name].[hash][extname]';
        },
        manualChunks: (id) => {
          if (id.includes('node_modules')) {
            if (id.includes('vue') || id.includes('react')) {
              return 'vendor-framework';
            }
            return 'vendor';
          }
        },
      },
    },
  },
});
```

### Phase 6: CDN Cache Headers Configuration

Configure cache headers based on detected CDN provider.

#### Vercel Configuration

**Create or update `vercel.json`:**
```json
{
  "headers": [
    {
      "source": "/_next/static/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    },
    {
      "source": "/static/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    },
    {
      "source": "/assets/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    },
    {
      "source": "/(.*).html",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=0, must-revalidate"
        }
      ]
    },
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-XSS-Protection",
          "value": "1; mode=block"
        }
      ]
    }
  ]
}
```

#### Cloudflare Pages Configuration

**Create `public/_headers`:**
```
# Static assets with content hashes - aggressive caching
/_next/static/*
  Cache-Control: public, max-age=31536000, immutable

/static/*
  Cache-Control: public, max-age=31536000, immutable

/assets/*
  Cache-Control: public, max-age=31536000, immutable

# HTML files - always revalidate
/*.html
  Cache-Control: public, max-age=0, must-revalidate

# Root HTML files
/
  Cache-Control: public, max-age=0, must-revalidate

# Security headers for all routes
/*
  X-Content-Type-Options: nosniff
  X-Frame-Options: DENY
  X-XSS-Protection: 1; mode=block
  Referrer-Policy: strict-origin-when-cross-origin
```

**Optional: Create `_redirects` for SPA routing:**
```
# Redirect all requests to index.html for SPA routing
/*    /index.html   200
```

#### Generic Configuration (Nginx Example)

**Create `nginx.conf` reference:**
```nginx
server {
    listen 80;
    server_name example.com;
    root /usr/share/nginx/html;
    index index.html;

    # Static assets with content hashes - long-term cache
    location ~* ^/(assets|_next/static)/.*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
        expires 1y;
        add_header Cache-Control "public, max-age=31536000, immutable";
        access_log off;
    }

    # HTML files - no cache
    location ~* \.html?$ {
        expires -1;
        add_header Cache-Control "public, max-age=0, must-revalidate";
    }

    # SPA routing fallback
    location / {
        try_files $uri $uri/ /index.html;
        add_header Cache-Control "public, max-age=0, must-revalidate";
    }

    # Security headers
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;
    add_header X-XSS-Protection "1; mode=block" always;
}
```

### Phase 7: Service Worker Cache Strategy (Optional)

For advanced cache control with service workers:

**Create `public/sw.js` (example):**
```javascript
// Service Worker for advanced caching strategies
const CACHE_VERSION = 'v1';
const STATIC_CACHE = `static-${CACHE_VERSION}`;
const DYNAMIC_CACHE = `dynamic-${CACHE_VERSION}`;

// Assets to precache
const PRECACHE_URLS = [
  '/',
  '/index.html',
  '/offline.html',
];

// Install event - precache static assets
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(STATIC_CACHE).then((cache) => {
      return cache.addAll(PRECACHE_URLS);
    })
  );
  self.skipWaiting();
});

// Activate event - clean up old caches
self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches.keys().then((cacheNames) => {
      return Promise.all(
        cacheNames
          .filter((name) => name !== STATIC_CACHE && name !== DYNAMIC_CACHE)
          .map((name) => caches.delete(name))
      );
    })
  );
  self.clients.claim();
});

// Fetch event - cache-first strategy for hashed assets
self.addEventListener('fetch', (event) => {
  const { request } = event;
  const url = new URL(request.url);

  // Cache-first for static assets with content hashes
  if (url.pathname.match(/\.(js|css|png|jpg|jpeg|gif|svg|woff2?)$/)) {
    event.respondWith(
      caches.match(request).then((cached) => {
        return cached || fetch(request).then((response) => {
          return caches.open(DYNAMIC_CACHE).then((cache) => {
            cache.put(request, response.clone());
            return response;
          });
        });
      })
    );
    return;
  }

  // Network-first for HTML
  if (url.pathname.endsWith('.html') || url.pathname === '/') {
    event.respondWith(
      fetch(request)
        .then((response) => {
          return caches.open(DYNAMIC_CACHE).then((cache) => {
            cache.put(request, response.clone());
            return response;
          });
        })
        .catch(() => {
          return caches.match(request).then((cached) => {
            return cached || caches.match('/offline.html');
          });
        })
    );
    return;
  }

  // Network-only for API requests
  event.respondWith(fetch(request));
});
```

**Register service worker in `index.html` or main entry:**
```javascript
// Register service worker
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker
      .register('/sw.js')
      .then((registration) => {
        console.log('Service Worker registered:', registration.scope);
      })
      .catch((error) => {
        console.log('Service Worker registration failed:', error);
      });
  });
}
```

### Phase 8: Build Verification

Add scripts to verify cache-busting is working:

**Add to `package.json`:**
```json
{
  "scripts": {
    "build": "next build",
    "build:verify": "next build && node scripts/verify-cache-busting.js",
    "cache:check": "node scripts/verify-cache-busting.js"
  }
}
```

**Create `scripts/verify-cache-busting.js`:**
```javascript
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');

// Verify Next.js build output
function verifyNextBuild() {
  const buildDir = path.join(process.cwd(), '.next/static');

  if (!fs.existsSync(buildDir)) {
    console.error('❌ Build directory not found. Run `npm run build` first.');
    process.exit(1);
  }

  const files = getAllFiles(buildDir);
  const hashedFiles = files.filter(f => /\.[a-f0-9]{8,}\.(js|css)$/.test(f));

  console.log(`✅ Found ${hashedFiles.length} hashed files in ${files.length} total files`);

  if (hashedFiles.length === 0) {
    console.error('❌ No content-hashed files found! Cache busting may not be working.');
    process.exit(1);
  }

  // Check for duplicate hashes (potential issue)
  const hashes = hashedFiles.map(f => f.match(/\.([a-f0-9]{8,})\./)?.[1]);
  const uniqueHashes = new Set(hashes);

  if (uniqueHashes.size < hashes.length) {
    console.warn('⚠️  Duplicate content hashes detected. This may indicate an issue.');
  }

  console.log('✅ Cache busting verification passed!');
}

// Verify Vite build output
function verifyViteBuild() {
  const distDir = path.join(process.cwd(), 'dist/assets');

  if (!fs.existsSync(distDir)) {
    console.error('❌ Build directory not found. Run `npm run build` first.');
    process.exit(1);
  }

  const files = getAllFiles(distDir);
  const hashedFiles = files.filter(f => /\.[a-f0-9]{8,}\.(js|css)$/.test(f));

  console.log(`✅ Found ${hashedFiles.length} hashed files in ${files.length} total files`);

  if (hashedFiles.length === 0) {
    console.error('❌ No content-hashed files found! Cache busting may not be working.');
    process.exit(1);
  }

  console.log('✅ Cache busting verification passed!');
}

function getAllFiles(dir, fileList = []) {
  const files = fs.readdirSync(dir);
  files.forEach(file => {
    const filePath = path.join(dir, file);
    if (fs.statSync(filePath).isDirectory()) {
      getAllFiles(filePath, fileList);
    } else {
      fileList.push(filePath);
    }
  });
  return fileList;
}

// Detect framework and run appropriate verification
if (fs.existsSync('.next')) {
  console.log('Verifying Next.js build...');
  verifyNextBuild();
} else if (fs.existsSync('dist')) {
  console.log('Verifying Vite build...');
  verifyViteBuild();
} else {
  console.error('❌ No build output found. Run `npm run build` first.');
  process.exit(1);
}
```

**Make script executable:**
```bash
chmod +x scripts/verify-cache-busting.js
```

### Phase 9: CI/CD Integration

Add cache busting verification to GitHub Actions:

**Update `.github/workflows/ci.yml`:**
```yaml
name: CI

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'

      - run: npm ci

      - name: Build
        run: npm run build
        env:
          GIT_COMMIT_SHA: ${{ github.sha }}

      - name: Verify cache busting
        run: npm run cache:check

      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: |
            .next/
            dist/
```

### Phase 10: Standards Tracking

Update `.project-standards.yaml`:

```yaml
standards_version: "2025.1"
last_configured: "[timestamp]"
components:
  cache-busting: "2025.1"
  cache-busting-framework: "[nextjs|vite]"
  cache-busting-cdn: "[vercel|cloudflare|none]"
  cache-busting-verified: true
```

### Phase 11: Documentation

Create `docs/CACHE_BUSTING.md`:

```markdown
# Cache Busting Strategy

This project uses content-based cache busting for optimal performance.

## How It Works

### Asset Hashing
- **JavaScript**: `app.[hash].js`
- **CSS**: `style.[hash].css`
- **Images**: `logo.[hash].png`

Content hashes change only when file content changes, enabling aggressive caching.

### Cache Headers

| Asset Type | Cache-Control | Duration |
|------------|---------------|----------|
| Hashed assets (JS, CSS) | `public, max-age=31536000, immutable` | 1 year |
| HTML files | `public, max-age=0, must-revalidate` | Always revalidate |
| Images | `public, max-age=86400` | 1 day |
| API responses | `no-store, no-cache` | Never cached |

### Build Process

1. Build generates unique content hashes
2. Hashes embedded in filenames
3. HTML references updated automatically
4. Old assets can be safely deleted

### CDN Configuration

Cache headers configured in:
- **Vercel**: `vercel.json`
- **Cloudflare**: `public/_headers`
- **Nginx**: `nginx.conf`

### Verification

Run `npm run cache:check` to verify:
- Content hashes present
- No duplicate hashes
- Proper file organization

### Deployment

1. Build: `npm run build`
2. Verify: `npm run cache:check`
3. Deploy: Assets automatically versioned
4. CDN: Cache headers applied

### Troubleshooting

**Problem**: Old assets still served
- **Solution**: Clear CDN cache or wait for TTL expiry

**Problem**: Build produces same hashes
- **Solution**: Ensure `generateBuildId` uses git commit SHA

**Problem**: Service worker serves stale content
- **Solution**: Update `CACHE_VERSION` in `sw.js`

## Best Practices

1. Never manually cache HTML files
2. Always use content hashes for static assets
3. Set `immutable` for hashed assets
4. Verify cache busting after build
5. Monitor CDN hit rates
```

### Phase 12: Updated Compliance Report

```
Cache-Busting Configuration Complete
=====================================

Framework: [Next.js 14.x | Vite 5.x]
CDN: [Vercel | Cloudflare | Generic]

Configuration Applied:
  ✅ Content hashing enabled ([hash] in filenames)
  ✅ Cache headers configured (immutable for static assets)
  ✅ CDN configuration created ([vercel.json | _headers])
  ✅ Build verification script added
  ✅ CI/CD verification integrated
  ✅ Documentation created

Next Steps:
  1. Run build to verify configuration:
     npm run build

  2. Verify cache busting is working:
     npm run cache:check

  3. Test locally with preview server:
     npm run preview  # Vite
     npm start        # Next.js

  4. Deploy and verify cache headers:
     curl -I https://your-domain.com/assets/app.[hash].js

  5. Monitor CDN cache hit rates in your CDN dashboard

Cache Strategy:
  - Static assets (JS, CSS, images): 1 year, immutable
  - HTML files: No cache, always revalidate
  - API routes: No cache

Documentation: docs/CACHE_BUSTING.md
```

## Output

Provide:
1. Compliance report with framework and CDN configuration status
2. List of changes made (if --fix) or proposed (if interactive)
3. Verification instructions and commands
4. CDN cache header examples
5. Next steps for deployment and monitoring

## See Also

- `/configure:all` - Run all compliance checks
- `/configure:status` - Quick compliance overview
- `/configure:workflows` - GitHub Actions workflow standards
- `/configure:dockerfile` - Container configuration with build caching
- **Next.js Documentation** - https://nextjs.org/docs/pages/api-reference/next-config-js
- **Vite Documentation** - https://vitejs.dev/config/build-options.html
- **Web.dev Caching Guide** - https://web.dev/http-cache/

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…