Autocomplete de moradas no Magento e Adobe Commerce
Possível, mas é trabalho de programador: os campos do checkout são componentes de interface renderizados por Knockout depois de a página carregar, e desde a versão 2.4.7 a Content Security Policy está em modo restrito nas páginas de pagamento. Esta página explica os dois obstáculos e dá o código.
Funciona no checkout: Sim — com trabalho de programador
Os formulários de morada do checkout são gerados dinamicamente (UI components com templates Knockout): os campos chamam-se street[0], postcode, city e country_id e só existem no DOM depois de o checkout arrancar. Desde a 2.4.7 as páginas de pagamento bloqueiam scripts externos e inline fora da lista branca da CSP: o domínio moradas.dev tem de ser autorizado num csp_whitelist.xml, e o código de ligação tem de estar num ficheiro, não inline.
Para que serve o widget no Magento: checkout (envio e faturação), livro de moradas na conta do cliente e formulários do tema fora do checkout, onde a CSP está em modo report-only por defeito.
Não testado numa loja real: baseado na documentação da Adobe e no código do Magento Open Source 2.4 (2 de outubro de 2026). Não existe extensão Moradas no Commerce Marketplace.
1. Autorizar o domínio na CSP
Num módulo seu (ou no módulo onde já guarda as personalizações da loja), crie etc/csp_whitelist.xml. script-src deixa carregar o widget.js; connect-src deixa o widget chamar a API e enviar o relatório de erros. Depois, limpe a cache.
<?xml version="1.0"?>
<!-- app/code/<Vendor>/<Module>/etc/csp_whitelist.xml -->
<csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp:etc/csp_whitelist.xsd">
<policies>
<policy id="script-src">
<values>
<value id="moradas" type="host">https://moradas.dev</value>
</values>
</policy>
<policy id="connect-src">
<values>
<value id="moradas-api" type="host">https://moradas.dev</value>
</values>
</policy>
</policies>
</csp_whitelist>
2. Carregar o widget e o código de ligação
Em Content › Design › Configuration › (a sua store view) › Other Settings › HTML Head › Scripts and Style Sheets, acrescente dois scripts: o widget e um ficheiro seu com o código de ligação, servido pela própria loja (por exemplo pub/moradas-checkout.js). Inline não serve nas páginas de checkout por causa da CSP.
<script src="https://moradas.dev/widget.js"></script> <script src="/moradas-checkout.js"></script>
3. Esperar pelos campos e ligar o widget
Os campos aparecem — e reaparecem, ao trocar de morada ou de método de pagamento — depois de a página carregar. Um MutationObserver liga o widget a cada campo street[0] novo e procura o código postal e a cidade no mesmo formulário:
// pub/moradas-checkout.js
(function () {
var attached = new WeakSet();
function scan() {
if (!window.PTAddress) return;
document.querySelectorAll('input[name="street[0]"]').forEach(function (input) {
if (attached.has(input)) return;
attached.add(input);
var form = input.closest('form') || document;
PTAddress.attach(input, {
fill: {
postal: form.querySelector('input[name="postcode"]'),
city: form.querySelector('input[name="city"]')
}
});
});
}
function start() {
scan();
new MutationObserver(scan).observe(document.body, { childList: true, subtree: true });
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start();
})();
- O widget escreve os valores como se o cliente os tivesse escrito (eventos
inputechange), que é o que as ligações Knockout escutam; confirme no seu checkout que o código postal preenchido fica guardado na morada ao avançar para o pagamento. - A morada no Magento pode ter duas ou três linhas (
street[1],street[2]); o widget usa só a primeira. - Em versões anteriores à 2.4.7 a CSP está em modo report-only em todas as páginas e o passo 1 não bloqueia nada; mantê-lo prepara a atualização.
O que o widget faz
O widget.js carrega-se com uma linha e liga-se ao campo da morada com PTAddress.attach. Enquanto o cliente escreve aparecem sugestões de ruas e localidades portuguesas; ao escolher, os campos indicados em fill recebem o código postal, a localidade, o concelho e o distrito. Numa rua com vários códigos postais, o CP7 exato chega com o número de porta. Se o serviço não responder, o formulário continua a funcionar como antes. Todas as opções — endpoint, fill, onSelect, onResolve, lang, beacon — estão na documentação do widget.
Porque é que o CP7 exato importa
Em Portugal uma rua pode ter vários códigos postais, por troços e pela paridade dos números. Na Avenida da Liberdade, em Lisboa, o n.º 196 tem o código 1250-147, e os números ímpares de 1 a 57 têm o 1250-139. Uma gralha no código postal pode mandar a encomenda para a morada errada.
E os dados dos clientes?
O Moradas não usa cookies e não guarda o texto pesquisado — só contagens agregadas de utilização e, se o beacon ficar ligado, um relatório mínimo quando o serviço falha. Pode remeter para a página de privacidade na política da sua loja.
Fontes (verificadas a 2 de outubro de 2026)
- Adobe Commerce: Customize checkout (UI components)
- Adobe Commerce: Add a new input form to checkout (templates Knockout)
- Adobe Commerce: Add a new field in the address form (formulários gerados dinamicamente)
- Adobe Commerce: Content Security Policies (csp_whitelist.xml)
- Adobe KB: Inline JavaScript issues on checkout page in CSP restricted mode
- Adobe Commerce user guide: Page setup (HTML Head › Scripts and Style Sheets)
- Magento 2 (GitHub): AttributeMerger.php — campos do formulário de morada
- Magento 2 (GitHub): form/element/abstract.js — nome do input (inputName)