Сколько лет уже кто-то говорит: «А можно, чтобы оно работало без интернета и ставилось на домашний экран?» И каждый раз после этой фразы начинается медленный спуск в персональный ад — ты лезешь в документацию по PWA, где всё разваливается на ровном месте, service worker живёт своей жизнью, кеш то работает, то ломается, App Router рушит весь твой кастомный пайплайн, а пользователи сидят на старых версиях, потому что вручную обновлять им, конечно, влом.

Словом, если ты когда-то пробовал прикрутить оффлайн-режим к Next.js-проекту, ты наверняка вспоминал всех, кто придумал этот стек. Я — точно. Поэтому, как человек, у которого было слишком много кофе и слишком мало терпения, я сделал единственное разумное: написал свою обёртку.

Так и появился next-pwa-pack — дроп-ин пакет, который превращает любой Next.js-проект в полноценное PWA, буквально одной строкой. Да, даже с App Router. Просто заворачиваешь свой layout в PWAProvider, и всё: приложение можно установить, оно кэширует страницы, работает оффлайн, синхронизирует вкладки и даже показывает отладочную панель, чтобы не гадать, сработало ли что-нибудь. Воткнул — и живи дальше.

А то:

Сервис-воркер? Напиши вручную.
Кешировать HTML? Сам придумай как.
Синхронизация вкладок? Ну это уже магия, удачи.
Обновление кеша после деплоя? Ну ты ж senior, сам справишься. ?

И ты сидишь, как идиот, с 300 вкладками про Workbox, cache-first, network-only, костылями из Stack Overflow 2019 года, и потеешь.

И вот я психанул

Серьёзно, просто устал.
И сделал пакет: next-pwa-pack

Никаких фреймворков внутри, никакой магии. Просто рабочий набор вещей, который превращает ваше унылое Next.js-приложение в PWA, без проклятий и бессонницы.

TL;DR (для тех, кто уже всё видел и ничему не верит)

  • Ставишь пакет

  • Оборачиваешь PWAProvider

  • Кешаешь страницы

  • Радуешься как человек

  • Всё.

Что умеет next-pwa-pack (и почему мне теперь не стыдно)

  • Регистрирует сервис-воркер

  • Кеширует HTML с TTL (по умолчанию 10 мин)

  • Обновляет кеш с сервера по Webhook или SSE

  • Поддерживает ручную и программную очистку кеша

  • Синхронизирует вкладки

  • Показывает offline.html, когда всё сломалось

  • Есть панель для девов: "обновить", "почистить", "забей, всё плохо"

Реальный код. Без сюрпризов

_layout.tsx:

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

export default function RootLayout({ children }) {
  return <PWAProvider>{children}</PWAProvider>;
}

/middleware.ts:

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

function originalMiddleware(request) {
  return NextResponse.next();
}

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

А дальше: живи

Хочешь принудительно обновить страницу?

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

await updateSWCache(["/blog", "/dashboard"]);

Хочешь сбросить всё к чертям?

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

await clearAllCache();

Хочешь вообще выключить кэш, потому что тебе плохо и ты в деве?

disablePWACache();

И главное — никаких непонятных магий

Сервис-воркер написан вручную, но один раз — и он просто делает, что должен:

  • Кеширует HTML

  • Кеширует статику

  • Показывает offline fallback

  • Слушает сообщения с клиента

  • Поддерживает skipWaiting, CLEAR_STATIC_CACHE, REVALIDATE_URL и другие заклинания

Зачем вам это

Если вы используете App Router в Next.js, PWA не просто не “работает из коробки”. Оно буквально не работает.
Или работает, но странно. А “странно” — это худшее состояние в продакшене.

next-pwa-pack решает это. Один раз. Без трёх дипломов по сервис-воркерам.

Всё, хватит

Если вы ещё не пишете сервис-воркеры вручную — берегите себя.
Если уже пишете — мои соболезнования.

А если просто хотите, чтобы PWA просто работалвот вам ссылка.

Подписывайтесь, ставьте звёздочку, ну или жалуйтесь здесь в комментариях.

Комментарии (4)


  1. ahdenchik
    07.08.2025 13:09

    Зумеры изобрели десктопный софт


    1. AcckiyGerman
      07.08.2025 13:09

      Таки мобильный, PWA ставится на рабочий стол в iOS/Android


  1. fransua
    07.08.2025 13:09

    Проблема действительно существует и без Next, довольно сложно это настроить правильно с первого раза.


  1. nin-jin
    07.08.2025 13:09

    В $mol это делается 1 строчкой:

    include \/mol/offline/install

    Завидуйте.