При портуванні Chrome-розширення на Firefox багато розробників стикаються з неочевидними відмінностями: різний API namespace, обов'язковий підпис через AMO та особливості Content Script. На основі нашого досвіду понад 10 років та більше ніж 50 успішних проєктів ми пропонуємо розробку Firefox Add-on під ключ з урахуванням цих нюансів. Понад 90% API збігається, але деталі вирішують.
Firefox Add-ons засновані на WebExtensions API — тій самій специфікації, що й Chrome Extensions. Більшість Chrome-розширень можна перенести на Firefox з мінімальними правками. Але є відмінності в деталях: підтримка API, процедура підпису, двигун розширень.
Відмінності Firefox від Chrome та складності портування
| Аспект | Firefox | Chrome |
|---|---|---|
| API namespace | browser.* (Promise) + chrome.* |
chrome.* (Callback) |
| Manifest | MV2 і MV3 (MV3 додано у Firefox 109+) | Тільки MV3 (MV2 застарів) |
| Background | Persistent background page (MV2) або SW (MV3) | Тільки Service Worker |
| Підпис | Обов'язковий через AMO | Не потрібен |
browser_style |
Підтримується | Не підтримується |
Перехід з chrome.* на browser.* — перший підводний камінь. Firefox використовує нативні Promise, тоді як Chrome покладається на callback'и. Без webextension-polyfill код не буде однаково працювати в обох браузерах. Content Script у Firefox ізольовані через Xray wrapper — прямий доступ до об'єктів сторінки неможливий, доводиться використовувати window.postMessage. Також обов'язковий підпис на AMO уповільнює release cycle, якщо не налаштувати CI з API-ключами.
Чому варто використовувати webextension-polyfill?
Поліфіл дозволяє писати код один раз, використовуючи browser.* API з Promise, і він буде працювати в Chrome. Це скорочує обсяг коду в 3 рази порівняно з дублюванням для кожного браузера. Однак потрібне тестування: деякі Chrome-специфічні функції можуть не мати аналогів.
Manifest V2: найбільш стабільний варіант для Firefox
{
"manifest_version": 2,
"name": "My Firefox Add-on",
"version": "1.0.0",
"description": "Опис доповнення",
"permissions": [
"storage",
"tabs",
"activeTab",
"https://*.example.com/*"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": {
"48": "icons/icon48.png",
"96": "icons/icon96.png"
}
},
"content_scripts": [
{
"matches": ["https://*.target-site.com/*"],
"js": ["content.js"]
}
],
"options_ui": {
"page": "options.html",
"open_in_tab": false
}
} Що таке Xray wrapper і як з ним працювати?
Xray wrapper — це механізм ізоляції Content Script у Firefox. Він запобігає прямому доступу до JavaScript-об'єктів сторінки, що підвищує безпеку, але ускладнює взаємодію. Для зв'язку між скриптом і сторінкою використовуйте window.postMessage або CustomEvent. Приклад:
// Content script -> Page script
window.postMessage({ source: 'myExtension', type: 'REQUEST_DATA' }, '*');
// Page script обробник
window.addEventListener('message', (e) => {
if (e.data?.source === 'myExtension' && e.data?.type === 'REQUEST_DATA') {
window.postMessage({
source: 'myPage',
type: 'RESPONSE_DATA',
payload: window.__MY_APP_STATE__,
}, '*');
}
});
Promise-based API і Content Script
Firefox підтримує нативні Promise в browser.*. Поліфіл webextension-polyfill робить код сумісним з Chrome:
import browser from 'webextension-polyfill'; // Firefox — нативні проміси
const tabs = await browser.tabs.query({ active: true, currentWindow: true });
const tab = tabs[0];
// Виконати скрипт (MV2)
await browser.tabs.executeScript(tab.id, {
code: 'document.body.style.background = "yellow"',
});
// Сховище
await browser.storage.local.set({ key: 'value' });
const result = await browser.storage.local.get('key');
У Firefox Content Scripts працюють в ізольованому світі (Xray wrapper) — вони не мають доступу до JavaScript-об'єктів сторінки безпосередньо. Для взаємодії зі сторінкою потрібен window.postMessage або CustomEvent.
Публікація, підпис і тестування через CI
Firefox вимагає підпису від Mozilla для будь-якого розширення, що поширюється не через AMO. Використовуйте web-ext — офіційний CLI від Mozilla — і налаштуйте підпис у CI (наприклад, GitHub Actions):
npm install -g web-ext
# Розробка з hot reload
web-ext run --source-dir ./dist --firefox-binary "/path/to/firefox"
# Збірка
web-ext build --source-dir ./dist --artifacts-dir ./artifacts
# Підпис (потрібні AMO API ключі)
web-ext sign \
--source-dir ./dist \
--api-key $AMO_JWT_ISSUER \
--api-secret $AMO_JWT_SECRETДля отримання API ключів: addons.mozilla.org/developers/addon/api/key/. Без підпису розширення можна встановити лише через about:debugging:
- Відкрити
about:debugging#/runtime/this-firefox - «Завантажити тимчасове доповнення»
- Вибрати
manifest.json - Працює до перезапуску браузера
Для корпоративного деплою без AMO — використовувати policies.json у Firefox Enterprise.
Додатково: підтримка контейнерів
Firefox підтримує Containers — ізольовані контексти з різними кукі. Доступ через API:const containers = await browser.contextualIdentities.query({}); // { cookieStoreId, name, color, icon }
// Відкрити вкладку в конкретному контейнері
await browser.tabs.create({
url: 'https://example.com',
cookieStoreId: 'firefox-container-1',
});
Як ми розробляємо Firefox Add-on?
Наші інженери з 10+ річним досвідом і більш ніж 50 успішними проєктами проходять через стандартний процес: аудит вимог, проєктування архітектури, реалізація з використанням TypeScript і React або vanilla JS, тестування в кількох версіях Firefox (включаючи Developer Edition і Nightly), автоматичний підпис через CI та публікація на AMO. Результат — повністю готове до використання розширення з документацією. Завдяки використанню webextension-polyfill розробка йде в 2 рази швидше порівняно з роздільною реалізацією, а обсяг коду скорочується на 60%.
Що входить у розробку Firefox Add-on
| Компонент | Опис |
|---|---|
| Вихідний код | Повний код розширення (MV2 або MV3) |
| Інтеграція з AMO | Підпис і публікація в магазині |
| Документація | Інструкція зі встановлення та налаштування |
| Гарантія сумісності | Підтримка останніх версій Firefox |
| Підтримка | 30 днів після здачі |
Терміни та вартість
Firefox Add-on, адаптований з Chrome-розширення, з підписом і публікацією на AMO — 2–3 робочих дні додатково до готового Chrome-розширення. Розробка нового доповнення з нуля — 4–8 днів залежно від функціональності. Вартість розраховується індивідуально і залежить від складності — зв'яжіться з нами для точної оцінки.
Замовте розробку Firefox Add-on: отримайте консультацію наших фахівців вже сьогодні. Ми гарантуємо сумісність з останніми версіями Firefox та повну документацію. Зв'яжіться з нами, щоб обговорити деталі вашого проєкту — ми надамо попередню оцінку протягом 24 годин.







