npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

next-pwa-pack

v2.0.0

Published

PWA cache provider for Next.js/React apps (service worker, manifest, offline page, SPA cache, offline)

Readme

next-pwa-pack

PWA cache provider для Next.js.
Автоматически регистрирует сервис-воркер, кэширует страницы и статику, добавляет PWA-манифест и offline-страницу, поддерживает офлайн-режим, SPA-навигацию, расширенные dev-инструменты, серверные и клиентские экшены для управления кэшем.


🚀 Быстрый старт

  1. Установите пакет:

    yarn add next-pwa-pack
    # или
    npm install next-pwa-pack
  2. После установки автоматически появятся файлы:

    • public/sw.js
    • public/manifest.json
    • public/offline.html
    • Также автоматически добавляется (или дополняется) файл с серверным экшеном revalidatePWAapp/actions.ts или src/app/actions.ts (если используется структура с папкой src).

    Если файлы не скопировались, выполните:

    node node_modules/next-pwa-pack/scripts/copy-pwa-files.mjs
    # или
    npx next-pwa-pack/scripts/copy-pwa-files.mjs
  3. Оберните приложение в провайдер:

    // _app.tsx или layout.tsx
    // если нужно сохранить компонент серверным - создайте свою обертку с "use client"
    import { PWAProvider } from "next-pwa-pack";
    
    export default function App({ children }) {
      return <PWAProvider>{children}</PWAProvider>;
    }
  4. Готово! Ваше приложение теперь поддерживает PWA, офлайн-режим и кэширование страниц.

HOC withPWA

Если вы используете SSR/Edge middleware или хотите инициировать серверные экшены (например, для ревалидации кэша на сервере), используйте HOC:

// /middleware.ts
import { withPWA } from "next-pwa-pack/hoc/withPWA";

function originalMiddleware(request) {
  // ...ваша логика
  return response;
}

export default withPWA(originalMiddleware, {
  revalidationSecret: process.env.REVALIDATION_SECRET!,
  sseEndpoint: "/api/pwa/cache-events",
  webhookPath: "/api/pwa/revalidate",
});

export const config = {
  matcher: ["/", "/(ru|en)/:path*", "/api/pwa/:path*"],
};

Аргументы хока:

  • originalMiddleware — ваша функция middleware (например, для i18n, авторизации и т.д.)
  • revalidationSecret — секрет для авторизации запросов на ревалидацию, нужен, чтобы никто кроме вас не мог в него стучаться
  • sseEndpoint — endpoint для SSE-событий (по умолчанию /api/pwa/cache-events)
  • webhookPath — endpoint для webhook-ревалидации (по умолчанию /api/pwa/revalidate)

Важно: В config.matcher обязательно укажите пути, которые должны обрабатываться этим middleware (например, корень сайта, локализованные маршруты и PWA endpoints).


📦 Структура экспорта

  • Компоненты:

    import { PWAProvider, usePWAStatus } from "next-pwa-pack";
  • HOC:

    import { withPWA } from "next-pwa-pack";

Клиентские экшены (Client Actions)

Импортируйте из next-pwa-pack/client-actions:

import {
  clearAllCache,
  reloadServiceWorker,
  updatePageCache,
  unregisterServiceWorkerAndClearCache,
  updateSWCache,
  disablePWACache,
  enablePWACache,
} from "next-pwa-pack/client-actions";
  • clearAllCache() — очистить все кэши
  • reloadServiceWorker() — перезагрузить сервис-воркер и страницу
  • updatePageCache(url?) — обновить кэш для страницы (по умолчанию текущей)
  • unregisterServiceWorkerAndClearCache() — удалить сервис-воркер и кэш
  • updateSWCache(urls) — обновить кэш для нескольких страниц во всех вкладках
  • disablePWACache() — временно отключить кэш (до перезагрузки)
  • enablePWACache() — включить кэш обратно

Серверные экшены (Server Actions)

После установки пакета в вашем проекте появится (или дополнится) файл app/actions.ts или src/app/actions.ts с функцией:

export async function revalidatePWA(urls: string[]) {
  // ...
}

Вызывайте её из server actions, server components или API routes для триггера PWA-ревалидации по URL.


🛠️ Кастомизация

Manifest.json

После установки пакета в public/manifest.json появится базовый манифест. Вы можете отредактировать его напрямую, добавив свои иконки, цвета, имя приложения и другие параметры:

{
  "name": "MyApp",
  "short_name": "MyApp",
  "theme_color": "#ff0000",
  "background_color": "#ffffff",
  "start_url": "/",
  "icons": [
    {
      "src": "/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ]
}

Путь к сервис-воркеру

Можно указать свой путь через проп swPath:

<PWAProvider swPath="/custom-sw.js">{children}</PWAProvider>

⚡ Dev-инструменты

С пропом devMode появляется панель "PWA Dev Tools" (в левом нижнем углу):

<PWAProvider devMode>{children}</PWAProvider>

Возможности панели:

  • Статус онлайн/оффлайн
  • Кнопка обновления приложения при наличии новой версии
  • Очистка кэша
  • Принудительная перезагрузка сервис-воркера
  • Принудительное обновление кэша текущей страницы
  • Полное удаление сервис-воркера и кэша
  • Глобальное отключение/включение кэша (до перезагрузки страницы)

🧩 API и хуки

Хук usePWAStatus

Следит за статусом PWA/Service Worker:

import { usePWAStatus } from "next-pwa-pack";
const { online, hasUpdate, swInstalled, update } = usePWAStatus();
  • online — онлайн/оффлайн статус
  • hasUpdate — доступно ли обновление
  • swInstalled — установлен ли сервис-воркер
  • update() — активировать новую версию приложения

Ревалидация кэша после мутаций

Если вы обновляете данные на сервере (например, через POST/PUT/DELETE), используйте:

  • revalidateTag (Next.js)
  • revalidatePWA (серверный экшен) или
  • updateSWCache (клиентский экшен)

Пример:

// server action
await revalidateTag("your-tag");
await revalidatePWA(["/your-page-url"]);

Пример: API-роут для внешней ревалидации (например, из админки)

Вы можете создать свой API-роут, чтобы инициировать ревалидацию кэша по тегам и/или URL извне (например, из админки или другого сервиса):

// app/api/webhook/revalidate/route.ts
import { NextRequest, NextResponse } from "next/server";
import { revalidateByTag, revalidatePWA } from "@/app/actions";
import { FetchTags } from "@/app/api/endpoints/backend";

export async function POST(request: NextRequest) {
  try {
    const { tags, secret, urls } = await request.json();

    if (secret !== process.env.REVALIDATION_SECRET) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    let successful = 0;
    let failed = 0;
    let tagsRevalidated = false;
    let urlsRevalidated = false;
    const validTags = Object.values(FetchTags);
    const invalidTags =
      tags?.filter((tag) => !validTags.includes(tag as any)) || [];

    if (invalidTags.length > 0) {
      return NextResponse.json(
        { error: `Invalid tags: ${invalidTags.join(", ")}` },
        { status: 400 }
      );
    }

    if (tags && tags.length > 0) {
      const tagResults = await Promise.allSettled(
        tags.map((tag) => revalidateByTag(tag as FetchTags))
      );
      successful = tagResults.filter((r) => r.status === "fulfilled").length;
      failed = tagResults.filter((r) => r.status === "rejected").length;
      tagsRevalidated = true;
    }

    if (urls && urls.length > 0) {
      await revalidatePWA(urls);
      urlsRevalidated = true;
    }

    return NextResponse.json({
      success: true,
      message: "Cache revalidation completed",
      tagsRevalidated,
      urlsRevalidated,
      tags: tags || [],
      urls: urls || [],
      successful,
      failed,
      timestamp: new Date().toISOString(),
    });
  } catch (error) {
    console.error("Webhook revalidation error:", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 }
    );
  }
}

Теперь вы можете отправлять POST-запросы на /api/webhook/revalidate с нужными тегами, URL и секретом — и инициировать обновление клиентского кэша из внешних систем.


Исключения из кэширования

В файле public/sw.js можно указать пути, которые не должны кэшироваться:

const CACHE_EXCLUDE = ["/api/", "/admin"];

🏗️ Как это работает

  • Service Worker кэширует HTML и статику, поддерживает TTL (по умолчанию 10 минут).
  • Offline.html — страница, которая показывается при отсутствии сети.
  • SPA-навигация — страницы кэшируются даже при переходах без перезагрузки.
  • Dev Tools — позволяют управлять кэшем и SW прямо из интерфейса.

❓ FAQ

  • Отключение кэша действует только до перезагрузки страницы.
  • Старый кэш не удаляется при отключении, просто не используется.
  • Включить кэш обратно — кнопкой или перезагрузкой страницы.
  • Файлы не появились?
    Запустите:
    node node_modules/next-pwa-pack/scripts/copy-pwa-files.mjs
  • Серверный экшен не появился?
    Запустите вручную скрипт для добавления server action:
    node node_modules/next-pwa-pack/scripts/copy-pwa-server-actions.mjs
    Этот скрипт создаст или дополнит файл app/actions.ts или src/app/actions.ts функцией revalidatePWA для серверной ревалидации кэша.

📦 Экспортируемые компоненты и экшены

  • PWAProvider — обёртка для приложения
  • usePWAStatus — хук статуса
  • Все утилиты для управления кэшем и SW (client-actions)
  • HOC withPWA для SSR/Edge middleware
  • Серверный экшен revalidatePWA (автоматически добавляется в actions.ts)

🏆 Как поддержать проект?

  • Поставьте звезду на GitHub ⭐
  • Создавайте pull requests, сообщайте о багах, предлагайте новые фичи или улучшения документации 🔧
  • Читайте нас на Medium
  • Следите за нами в Twitter
  • Лайкайте нашу страницу на LinkedIn 👍

🤝 Contributing

Хотите поучаствовать в разработке? Сделайте Fork репозитория, внесите изменения и отправьте pull request. Мы будем рады вашим предложениям!


©️ License

MIT