A partir do Chrome 148, todas as APIs de extensão do Chrome estão disponíveis no namespace browser, além do namespace chrome atual. Por exemplo, browser.tabs.create({}) e chrome.tabs.create({}) são equivalentes.
O namespace está disponível em qualquer lugar em que você possa chamar APIs de extensão, incluindo scripts de conteúdo, service workers e documentos fora da tela. Ele aponta para os
mesmos objetos de API que chrome, então chrome.tabs === browser.tabs.
O namespace browser surgiu do trabalho no
WebExtensions Community Group (WECG),
um grupo da comunidade W3C em que os fornecedores de navegadores colaboram em padrões de extensão
compartilhados. O namespace chrome não vai desaparecer. Os dois namespaces vão continuar funcionando.
Decidir se você quer adotar o namespace do navegador
Se você estiver usando webextension-polyfill, pule para Uma observação para usuários de polyfill antes de mudar qualquer outra coisa. A resposta é diferente para você.
Se você estiver criando uma nova extensão, defina
minimum_chrome_version
como "148" e use browser incondicionalmente. Você pode parar de ler aqui. O restante desta seção é para extensões atuais que estão decidindo como adotar.
Verificar quais versões do Chrome seus usuários estão usando
Se você tiver uma extensão, verifique quais versões do Chrome seus usuários estão executando antes de mudar. O Chrome é atualizado automaticamente, mas alguns usuários desativam as atualizações e outros estão em dispositivos mais antigos que não podem executar a versão mais recente. Confirme com seus próprios dados de análise. Se você ainda não configurou a análise ainda, consulte Monitorar a performance da extensão com o Google Analytics 4 para começar.
Em seguida, escolha um caminho:
- Se seus usuários estiverem no Chrome 148 ou mais recente, adote incondicionalmente.
- Se uma parte significativa dos seus usuários estiver no Chrome 147 ou anterior, use a proteção de tempo de execução.
Adotar incondicionalmente
Defina minimum_chrome_version
no seu manifesto e use browser incondicionalmente. Não é necessária nenhuma proteção de tempo de execução:
{
"minimum_chrome_version": "148"
}
Use um lançamento gradual ao aumentar minimum_chrome_version. Se algo
der errado, você poderá reverter a extensão na
Chrome Web Store.
Usar a proteção de tempo de execução
Adicione o snippet a seguir no início do código de inicialização da extensão antes de referenciar browser em qualquer outro lugar:
if (!globalThis.browser) {
globalThis.browser = chrome;
// Consider firing an analytics event here to measure how often
// your users hit this fallback path.
}
Isso torna browser um alias para chrome em versões anteriores, para que o restante do código possa usar browser incondicionalmente.
Uma observação para usuários de polyfill
Se a extensão usar
webextension-polyfill, ela
se tornará uma operação nula no Chrome 148 e versões mais recentes. O polyfill ignorou o encapsulamento quando browser já estava definido, presumindo que o navegador host já havia fornecido a API.
Uma tentativa anterior de enviar o namespace no Chrome 136 foi revertida por
esse motivo: com browser recém-definido, o polyfill parou de encapsular, mas
o browser.runtime.onMessage do Chrome ainda não oferecia suporte a listeners
que retornam promessas, que o polyfill estava fornecendo. As extensões que dependiam desse padrão foram interrompidas. O Chrome 148 envia o namespace e os listeners onMessage nativos que retornam promessas juntos para evitar essa lacuna.
Você pode remover a dependência de polyfill quando a base de usuários mudar para o Chrome 148.
Outros recursos
Respostas assíncronas em runtime.sendMessage
No Chrome 148, os listeners runtime.onMessage podem retornar uma Promise diretamente para enviar uma resposta assíncrona. Isso funciona se você chamar usando chrome.* ou browser.*.
Anteriormente, a única maneira de responder de forma assíncrona era retornar um literal true do listener e chamar sendResponse mais tarde:
// Old pattern - requires returning true to keep the channel open
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
fetch('https://example.com')
.then(response => sendResponse({ statusCode: response.status }));
return true; // keeps the message channel open for the async response
});
Agora você pode retornar uma Promise (ou usar uma função async) diretamente:
// New pattern - return a promise or use async/await
browser.runtime.onMessage.addListener(async (message, sender) => {
const response = await fetch('https://example.com');
return { statusCode: response.status };
});
O padrão return true continua funcionando, então o código atual não precisa ser alterado.