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. 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 offscreen. Ele aponta para os mesmos objetos de API que chrome, então chrome.tabs === browser.tabs.
O namespace browser é resultado do trabalho do
WebExtensions Community Group (WECG),
um grupo da comunidade W3C em que 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 Observação para usuários de polyfill antes de mudar qualquer outra coisa porque 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ê já tiver uma extensão, verifique quais versões do Chrome seus usuários estão usando antes de mudar. O Chrome é atualizado automaticamente, mas alguns usuários desativam as atualizações, e outros usam dispositivos mais antigos que não conseguem executar a versão mais recente. Confirme com seus próprios dados de análise. Se você ainda não configurou o Google Analytics, consulte Monitore a performance da sua extensão com o Google Analytics 4 para começar.
Em seguida, escolha um caminho:
- Se os usuários estiverem no Chrome 148 ou mais recente, adote incondicionalmente.
- Se uma parte significativa dos seus usuários estiver usando o Chrome 147 ou uma versão anterior, use a proteção de tempo de execução.
Adotar incondicionalmente
Defina minimum_chrome_version
no manifesto e use browser incondicionalmente. Não é necessário usar 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 ambiente 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 faz com que browser seja um alias de chrome em versões anteriores. Assim, o restante do
código pode usar browser incondicionalmente.
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 pulou 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
este motivo: com browser recém-definido, o polyfill parou de encapsular, mas
o browser.runtime.onMessage do Chrome ainda não era compatível com listeners
que retornavam promessas, que o polyfill estava fornecendo. As extensões que dependiam desse
padrão pararam de funcionar. O Chrome 148 envia o namespace e os listeners nativos de retorno de promessa
onMessage juntos para evitar essa lacuna.
Você pode remover a dependência de polyfill quando sua base de usuários migrar para o Chrome 148.
Outros recursos
Respostas assíncronas em runtime.sendMessage
No Chrome 148, os listeners de runtime.onMessage podem retornar um Promise diretamente
para enviar uma resposta assíncrona. Isso funciona se você chamar usando chrome.* ou
browser.*.
Antes, 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 é possível retornar um 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.