Rozszerzenia ChromeManifest V3AktualizacjeDevOps

Jak szybciej dostarczać aktualizacje rozszerzeń Chrome do użytkowników

Opublikowano · Zaktualizowano · 10 min czytania · Zespół Optymized

Wysyłasz krytyczną poprawkę do Chrome Web Store. Przechodzi review w kilka godzin. I potem... cisza. Użytkownicy nadal korzystają ze starej wersji. Niektórzy przez godziny, inni przez dni. Mechanizm auto-aktualizacji Chrome to czarna skrzynka, a jeśli manifest wymaga ponownej zgody na uprawnienia, aktualizacja może utknąć na czas nieokreślony.

Po wydaniu ponad 100 wersji rozszerzenia Panel Pro dokładnie wiemy, które ustawienia manifestu spowalniają aktualizacje, a które je przyspieszają. Ten poradnik obejmuje wszystko: zakres uprawnień, konfigurację content scriptów i budowę sprawdzania wersji w czasie rzeczywistym.

Jak naprawdę działają aktualizacje rozszerzeń Chrome

Chrome sprawdza aktualizacje rozszerzeń mniej więcej co 5 godzin. Gdy znajdzie nową wersję w Chrome Web Store, pobiera ją i instaluje cicho w tle. Użytkownik nie widzi żadnego komunikatu — chyba że zmieniłeś uprawnienia.

To "chyba że" jest źródłem większości problemów. Jeśli nowa wersja wymaga uprawnień lub dostępu do hostów, których nie było w poprzedniej wersji, Chrome:

  1. Natychmiast wyłącza rozszerzenie
  2. Wyświetla znacznik na ikonie puzzla w pasku narzędzi
  3. Czeka, aż użytkownik ręcznie kliknie "Włącz ponownie" i zaakceptuje nowe uprawnienia

Dopóki użytkownik tego nie zrobi, utknął na starej wersji z wyłączonym rozszerzeniem. Dla krytycznego narzędzia biznesowego, takiego jak rozszerzenie do zarządzania reklamami, jest to nieakceptowalne.

1. Zawęź host_permissions do minimum

Pole host_permissions w manifest.json to przyczyna numer jeden problemów z aktualizacjami. Każdy nowy origin wywołuje proces ponownej zgody.

Źle — zbyt szeroko

"host_permissions": [
  "<all_urls>"
]

To żąda dostępu do każdej strony. Przyszłe zawężenie zakresu nigdy nie wywoła ponownej zgody (zacząłeś od maksimum), ale review Google będzie wolniejszy, a użytkownicy mogą w ogóle nie zainstalować.

Dobrze — konkretne originy

"host_permissions": [
  "https://ads.allegro.pl/*",
  "https://api.example.com/*"
]

Tylko te originy, których faktycznie potrzebujesz. Jeśli później będziesz potrzebować https://analytics.allegro.pl/*, to wywoła ponowną zgodę — ale możesz się na to przygotować.

Najlepiej — planuj z wyprzedzeniem

"host_permissions": [
  "https://*.allegro.pl/*",
  "https://api.example.com/*"
]

Użyj wildcard na subdomenę dla platform, na których wiesz, że będziesz potrzebować wielu subdomen. Dodanie analytics.allegro.pl później nie wywoła ponownej zgody, bo jest już objęte przez *.allegro.pl.

2. Content scripts i wzorce dopasowań

Content scripts mają własne pole matches, które określa, na jakich stronach się uruchamiają. Zmiana tych wzorców nie wywołuje ponownej zgody na uprawnienia — ale błędna konfiguracja wciąż opóźnia aktualizacje w inny sposób.

Wzorce, które powodują problemy

"content_scripts": [{
  "matches": ["<all_urls>"],
  "js": ["content.js"]
}]

Uruchamianie na każdej stronie powoduje wolniejszy review od Google. Zwiększa też ryzyko konfliktów z innymi rozszerzeniami i sprawia, że rozszerzenie wygląda podejrzanie dla użytkowników.

Wzorce zrobione dobrze

"content_scripts": [{
  "matches": [
    "https://ads.allegro.pl/*",
    "https://allegro.pl/ads/*"
  ],
  "js": ["content.js"],
  "run_at": "document_idle"
}]

Konkretne wzorce dopasowań. Google recenzuje je szybciej, bo może zweryfikować, że rozszerzenie dotyka tylko tych stron, do których deklaruje dostęp.

Używaj run_at z głową

Pole run_at nie wpływa bezpośrednio na szybkość aktualizacji, ale ma znaczenie dla doświadczenia użytkownika po aktualizacji:

  • document_idle (domyślne) — najbezpieczniejsze, uruchamia się po załadowaniu strony
  • document_end — uruchamia się po gotowości DOM, ale przed zasobami podrzędnymi
  • document_start — uruchamia się przed wszystkim innym, może spowalniać stronę

Używaj document_idle, chyba że masz konkretny powód, by tego nie robić. Rozszerzenia spowalniające ładowanie stron dostają niższe oceny i więcej odinstalowań.

3. Pole permissions — zaplanuj powierzchnię API z góry

Tablica permissions (oddzielna od host_permissions) kontroluje dostęp do API Chrome, takich jak storage, tabs,alarms i notifications. Dodanie nowego uprawnienia tutaj również wywołuje ponowną zgodę.

Praktyczne rady

  • Zażądaj wszystkiego, czego będziesz potrzebować, w v1. Jeśli wiesz, że za miesiąc dodasz powiadomienia, dodaj notifications do permissions teraz. Nieużywane uprawnienie jest lepsze niż ponowna zgoda, która wyłącza rozszerzenie.
  • Użyj optional_permissions dla funkcji, których możesz nie wydać. Są żądane w runtime przez chrome.permissions.request() i nigdy nie wywołują ponownej zgody przy aktualizacji.
  • Nigdy nie usuwaj i nie dodawaj ponownie uprawnienia. Usunięcie tabs w v2 i dodanie go z powrotem w v3 wywoła ponowną zgodę w v3.

Przykład optional_permissions

{
  "permissions": ["storage", "alarms"],
  "optional_permissions": ["notifications", "downloads"],
  "optional_host_permissions": ["https://analytics.example.com/*"]
}

Użytkownicy przyznają opcjonalne uprawnienia, gdy po raz pierwszy używają funkcji, która ich potrzebuje. Bez ponownej zgody przy aktualizacji, bez wyłączonego rozszerzenia, bez utraconych użytkowników.

4. Powiadamiaj użytkowników w czasie rzeczywistym

Nawet jeśli zrobisz wszystko dobrze z uprawnieniami i wzorcami dopasowań, ~5-godzinny cykl aktualizacji Chrome oznacza, że użytkownicy mogą korzystać z nieaktualnego kodu przez godziny. Dla krytycznych poprawek to za wolno.

Rozwiązanie: sprawdzaj opublikowaną wersję z wnętrza rozszerzenia i informuj użytkownika o dostępnej aktualizacji.

Dlaczego nie GitHub Action?

Można pomyśleć, że CI/CD to właściwe miejsce do sprawdzania wersji. Mamy GitHub Action do wykrywania eskalacji uprawnień i świetnie sprawdza się w łapaniu problemów przed publikacją. Ale do powiadamiania użytkowników o dostępnych aktualizacjach CI/CD nie pomoże:

  • GitHub Action działa w Twoim pipeline, nie w przeglądarce użytkownika
  • Spala minuty CI przy każdym sprawdzeniu
  • Nie może powiedzieć użytkownikowi "hej, kliknij Aktualizuj"

Potrzebujesz lekkiego API, które Twoje rozszerzenie może wywołać w runtime, aby porównać swoją wersję z wersją opublikowaną w Chrome Web Store.

Chrome Extension Version API

Zbudowaliśmy i udostępniliśmy jako open source chrome-extension-version-api — jednoendpointowy serwis .NET, który odpytuje Chrome Web Store o opublikowaną wersję dowolnego rozszerzenia. Działa jako kontener Docker z wbudowanym cache.

Użycie API

GET /check-published-extension-version/{extensionId}

// Odpowiedź (200 OK)
{
  "version": "1.23.4",
  "cached": false,
  "checkedAt": "2026-03-16T12:00:00Z"
}

Wdrożenie z Docker

docker run -p 8080:8080 ghcr.io/toumash/chrome-extension-version-api:latest

Wdróż za istniejącym ingressem lub reverse proxy. Nie wymaga bazy danych, konfiguracji i prawie żadnych zasobów. Ustaw CacheTtlMinutes, aby kontrolować, jak często faktycznie odpytuje Chrome Web Store (domyślnie: 5 minut).

Implementacja po stronie rozszerzenia

W content scripcie — kodzie, który działa na stronie, z której użytkownik aktywnie korzysta — sprawdź opublikowaną wersję i wyświetl powiadomienie o aktualizacji bezpośrednio w interfejsie:

// content.js — działa na stronie, z której użytkownik korzysta
const EXTENSION_ID = chrome.runtime.id;
const VERSION_API = 'https://your-api.example.com';

async function checkForUpdate() {
  const localVersion = chrome.runtime.getManifest().version;
  const res = await fetch(
    `${VERSION_API}/check-published-extension-version/${EXTENSION_ID}`
  );
  const { version: storeVersion } = await res.json();

  if (storeVersion && storeVersion !== localVersion) {
    // Pokaż baner aktualizacji na stronie, z której użytkownik korzysta
    const banner = document.createElement('div');
    banner.textContent = `Dostępna aktualizacja (v${storeVersion}). Przeładuj stronę.`;
    banner.style.cssText =
      'position:fixed;bottom:16px;right:16px;padding:12px 20px;' +
      'background:#f97316;color:#fff;border-radius:8px;z-index:99999;' +
      'font-family:sans-serif;cursor:pointer;';
    banner.onclick = () => location.reload();
    document.body.appendChild(banner);
  }
}

// Sprawdź przy ładowaniu strony
checkForUpdate();

Użytkownik widzi badge "NEW" na ikonie rozszerzenia i wie, że trzeba zaktualizować. Możesz też wyświetlić baner w popup lub UI content scriptu.

Dlaczego to lepsze niż czekanie na Chrome

~5h

Domyślny interwał sprawdzania Chrome

30min

Interwał sprawdzania Twojego API

0

Spalonych minut CI

FAQ

Jak często Chrome sprawdza aktualizacje rozszerzeń?

Mniej więcej co 5 godzin, ale rzeczywisty interwał może się różnić. Chrome może grupować sprawdzenia, a warunki sieciowe mogą dodać opóźnienie. Nie możesz kontrolować tego interwału z poziomu kodu rozszerzenia, ale możesz zbudować własny mechanizm sprawdzania wersji (patrz sekcja 4 powyżej), aby powiadamiać użytkowników szybciej.

Czy mogę wymusić natychmiastową aktualizację rozszerzenia Chrome?

Użytkownicy mogą wejść na chrome://extensions, włączyć Tryb programisty i kliknąć "Aktualizuj". Lepszym podejściem jest użycie API do sprawdzania wersji, aby wykrywać nowe wersje i powiadamiać użytkowników badge'em lub komunikatem w aplikacji.

Czy zmiany uprawnień spowalniają aktualizacje?

Tak. Jeśli nowa wersja dodaje permissions lub host_permissions, których nie było w poprzedniej wersji, Chrome wyłącza rozszerzenie i wyświetla dialog ponownej zgody. Rozszerzenie pozostaje wyłączone do momentu ręcznego zatwierdzenia przez użytkownika.

Dlaczego nie użyć po prostu <all_urls>, żeby uniknąć ponownej zgody?

Choć <all_urls> unika przyszłej ponownej zgody dla host permissions, powoduje wolniejszy review w Chrome Web Store, odstrasza użytkowników podczas instalacji i może spowodować oflagowanie rozszerzenia. Zamiast tego użyj wildcard na subdomenę (np. *.example.com) dla platform, na które celujesz.

Powiązane artykuły

Potrzebujesz pomocy z szybszymi aktualizacjami?

Wydaliśmy ponad 100 wersji rozszerzeń i zbudowaliśmy narzędzia, które czynią aktualizacje bezproblemowymi. Niezależnie czy potrzebujesz pomocy z konfiguracją manifestu, CI/CD czy sprawdzaniem wersji w czasie rzeczywistym — możemy pomóc.

Kto za tym stoi

Tomasz Dłuski

Tomasz Dłuski

Założyciel & CEO

Senior Software Engineer z 10+ letnim doświadczeniem. W poprzedniej firmie był częścią firmy, która wyskalowała się z 5 do 50+ inżynierów. Teraz buduje Optymized — firmę, która łączy doświadczenie w dostarczaniu projektów enterprise z własnymi produktami SaaS. Maintainer CRXJS (3.9k stars na GitHubie), jednego z najpopularniejszych narzędzi do budowy rozszerzeń przeglądarek.

Porozmawiajmy o Twoim projekcie

Potrzebujesz rozszerzenia do przeglądarki, dedykowanego zespołu, czy konsultacji technicznej? Znajdźmy najlepsze podejście razem.

lub napisz do nas