A era da digitação está a terminar. Como discutimos no nosso Guia SEO Voice Search, em 2026, o comportamento do utilizador mudou fundamentalmente. O design “Teclado-primeiro” está a tornar-se um conceito legado.
Com o surgimento da “Ambient AI”, em que os computadores são ouvintes omnipresentes e não apenas ecrãs, a expectativa de Interação Multimodal (Voz, Gesto, Olhar) é padrão. Os utilizadores não querem escrever “Programador WordPress Varsóvia”; querem perguntar: “Encontra-me um especialista WordPress por perto.”
Enquanto os widgets de avatar AI renderizam avatares de conversação 3D impressionantes, acreditamos que o primeiro passo crítico para a maioria dos sites WordPress de alto desempenho é uma interface de pesquisa por voz robusta, eficiente e nativa.
Este estudo de caso documenta como construo o botão de pesquisa por voz na barra de pesquisa do wppoland.com: zero plugins, zero inchaço, JavaScript simples. Aborda a implementação técnica, para onde vai realmente o áudio, que browsers a suportam em outubro de 2026 e por que escolhemos este caminho em vez de widgets pesados de terceiros.
Porque os widgets de avatar IA prejudicam Core Web Vitals
Antes de escolhermos a pesquisa por voz nativa, comparámo-la com widgets incorporáveis de “Avatar AI”.
Como os widgets de avatar IA atrasam o LCP e o INP
Avatares de conversação são visualmente deslumbrantes. Usam WebGL para renderizar rostos realistas que sincronizam os lábios com áudio gerado por IA. No entanto, para um site corporativo ou portfólio de alto desempenho, introduzem “Dívida de Desempenho” significativa:
- LCP (Largest Contentful Paint): Carregar um motor 3D (como Three.js) e ativos de personagens bloqueia frequentemente a thread principal e atrasa o LCP.
- INP (Interaction to Next Paint): Ciclos de animação constantes e ouvintes de eventos podem causar micro-interrupções ao fazer scroll ou clicar.
- Encargo de Privacidade: Enviar fluxos de áudio contínuos para um servidor de terceiros aumenta as barreiras de conformidade com o RGPD.
O Nosso Objetivo: Permitir interação por voz contextual, para que os utilizadores possam falar com o site naturalmente, sem sacrificar a nossa pontuação de PageSpeed nem acrescentar mais um script de terceiros.
Web Speech API para pesquisa por voz
O Chrome, o Edge e o Safari incluem uma interface que muitos programadores ignoram: a Web Speech API. Tem duas metades. O SpeechRecognition converte o áudio do microfone em texto e o SpeechSynthesis converte texto em áudio falado. A especificação é um Draft Community Group Report mantido no repositório do W3C Audio Community Group, não uma Recomendação do W3C, e o MDN classifica o SpeechRecognition como “disponibilidade limitada”, ou seja, não é Baseline.
- Sem bibliotecas externas: O motor de reconhecimento é fornecido pelo browser, por isso o único código que envia é a ligação entre a API e o formulário de pesquisa.
- Sem contrato com fornecedores: Não precisa de subscrever uma API de speech-to-text nem de gerir chaves.
- Nem sempre local: O reconhecimento corre onde o browser decidir. A secção seguinte explica porque é que isso importa.
Web Speech API vs. widget de avatar IA
| Funcionalidade | Web Speech API Nativa | Widget AI Externo |
|---|---|---|
| Tamanho do Pacote | 0kb de biblioteca (Nativo do Browser) | Script do fornecedor, motor 3D e ativos da personagem |
| Privacidade | Serviço do fornecedor do browser por omissão, no dispositivo a pedido | Nuvem do fornecedor do widget |
| Desempenho | Nada é carregado até o utilizador tocar no microfone | Uso Elevado de CPU |
| Integração | Código Personalizado (<50 linhas) | Script Drop-in |
| Custo | Grátis | Tarifário do fornecedor |
| Visuais | Invisível (Guiado por UI) | Avatar 3D |
Para wppoland.com, a escolha foi clara: o desempenho é a nossa marca. Escolhemos Nativo.
Para onde a Web Speech API envia o áudio da voz
A Web Speech API não promete processamento local. O guia do MDN sobre a API é explícito: “Por omissão, usar o reconhecimento de voz numa página web envolve um motor de reconhecimento baseado em servidor. O seu áudio é enviado para um serviço web para ser processado, por isso não funciona offline.” (MDN, Using the Web Speech API, tradução própria). No Chrome, esse serviço web pertence ao fornecedor do browser, não a si nem ao autor de um plugin.
A especificação oferece agora uma alternativa opcional. Definir recognition.processLocally = true antes de start() indica um requisito de que o reconhecimento aconteça no dispositivo. O modo no dispositivo precisa de um pacote de idioma por cada língua. Se o pacote faltar, start() falha com o erro language-not-supported. Dois métodos estáticos gerem os pacotes:
SpeechRecognition.available({ langs, processLocally })resolve paraunavailable,downloadable,downloadingouavailable.SpeechRecognition.install({ langs })descarrega os pacotes e resolve paratrueoufalse.
Ambos os métodos são controlados pela Permissions-Policy on-device-speech-recognition, cuja allowlist por omissão é self, por isso um iframe de outra origem não os pode chamar a menos que a página principal delegue a funcionalidade.
Para um site que serve visitantes da UE, a consequência prática é simples: um botão de voz no modo por omissão envia a fala para o serviço de reconhecimento do fornecedor do browser, e o seu aviso de privacidade deve dizê-lo em linguagem clara. A nossa afirmação de “privacidade primeiro” só se mantém no sentido mais estreito de que nenhum plugin de terceiros nem fornecedor de widgets recebe o áudio.
Como pedir reconhecimento no dispositivo com alternativa
const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
const lang = document.documentElement.lang || 'pt-PT';
const recognition = new SR();
recognition.lang = lang;
if (typeof SR.available === 'function') {
const status = await SR.available({ langs: [lang], processLocally: true });
if (status === 'available') {
recognition.processLocally = true; // o áudio fica no dispositivo
} else if (status === 'downloadable') {
// Oferecer o download a partir de uma ação do utilizador; caso contrário, usar o motor do servidor
}
}O MDN observa que as implementações com reconhecimento no dispositivo o suportam sem prefixos, por isso available() só existe no construtor sem prefixo. Detete a funcionalidade, nunca a assuma.
Que browsers suportam a Web Speech API em 2026
A tabela abaixo vem do browser-compat-data do MDN, versão 8.1.6 (15 de outubro de 2026). Os números de versão indicam a primeira versão com suporte.
| Browser | SpeechRecognition | No dispositivo (processLocally, available(), install()) | SpeechSynthesis |
|---|---|---|---|
| Chrome (desktop e Android) | 139 sem prefixo, 33 como webkitSpeechRecognition | 139 (experimental) | 33 |
| Edge | 139 sem prefixo, 79 com prefixo | 139 (experimental) | 14 |
| Safari (macOS) | 14.1, só com o prefixo webkit | Não suportado | 7 |
| Safari (iOS) | 14.5, só com o prefixo webkit | Não suportado | 7 |
| Firefox | Apenas versões de pré-visualização | Apenas versões de pré-visualização | 49 |
| Samsung Internet | 30.0 sem prefixo, 2.0 com prefixo | Sem dados | 3.0 |
Daqui resultam três conclusões para um tema WordPress. Mantenha a alternativa window.SpeechRecognition || window.webkitSpeechRecognition, porque o Safari continua a ter apenas o nome com prefixo. Esconda o botão do microfone quando nenhum dos construtores existir, porque os utilizadores das versões estáveis do Firefox veriam um botão que não faz nada. Trate o reconhecimento no dispositivo, por agora, como um extra exclusivo do Chromium.
Como implementar pesquisa por voz com JavaScript
Adicionámos esta funcionalidade ao nosso componente SearchInput.astro. Isto garante que a barra de pesquisa é a única fonte de verdade tanto para consultas de texto como de voz.
Passo 1: Deteção de funcionalidade
Primeiro, devemos respeitar as capacidades do browser do utilizador. Nunca assumimos que uma API existe.
// Verificar se o browser suporta SpeechRecognition
if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
const voiceBtn = document.getElementById("voice-search-btn");
voiceBtn.classList.remove("hidden"); // Mostrar botão apenas se suportado
}Passo 2: Código de reconhecimento de voz
Aqui está uma versão simplificada do código. Note a alternativa com o prefixo webkit: os browsers Chromium aceitam o nome sem prefixo a partir da versão 139, mas o Safari continua a expor apenas webkitSpeechRecognition.
// 1. Inicializar
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const recognition = new SpeechRecognition();
// 2. Configuração
recognition.continuous = false; // Parar após uma frase
recognition.interimResults = false; // Retornar apenas resultados finais
recognition.lang = document.documentElement.lang || 'pt-PT'; // Suporte dinâmico de idioma
// 3. Manipuladores de Eventos
recognition.onstart = () => {
// Feedback Visual é crucial para Voice UI
voiceBtn.classList.add("text-red-500", "animate-pulse");
searchInput.placeholder = "A ouvir...";
};
recognition.onend = () => {
// Limpar estado da UI
voiceBtn.classList.remove("text-red-500", "animate-pulse");
searchInput.placeholder = "Pesquisar...";
};
recognition.onresult = (event) => {
// 4. Capturar Transcrição
const transcript = event.results[0][0].transcript;
searchInput.value = transcript;
// 5. UX: Auto-enviar após pausa natural
// Isto remove a fricção de clicar "Pesquisar" novamente
setTimeout(() => searchInput.form.submit(), 500);
};
// 6. Gatilho
voiceBtn.addEventListener('click', () => recognition.start());Se não definir lang, a especificação recorre ao idioma da raiz do documento, por isso um atributo <html lang> correto já dá a cada versão linguística o idioma de reconhecimento certo.
Passo 3: Tratamento de erros
O uso no mundo real é confuso. Utilizadores recusam permissões de microfone, ou os ambientes são barulhentos. Adicionámos tratamento de erros para voltar à entrada de texto se o microfone estiver bloqueado.
recognition.onerror = (event) => { console.log('Erro de Voz:', event.error); };
Que erros de reconhecimento de voz tratar
O evento error traz um de oito códigos definidos na especificação. Cada um pede uma reação diferente:
| Código de erro | O que diz a especificação | Reação sensata |
|---|---|---|
no-speech | Não foi detetada fala | Ignorar ou repor discretamente, o utilizador simplesmente não falou |
aborted | A entrada de voz foi interrompida, por exemplo pelo utilizador | Repor a interface sem mensagem |
audio-capture | A captura de áudio falhou | Mostrar um erro de microfone |
network | Falhou uma comunicação de rede necessária | Sugerir escrever, o motor no servidor não está acessível |
not-allowed | Bloqueado por razões de segurança, privacidade ou preferência do utilizador | Informar que o microfone está bloqueado nas definições do browser |
service-not-allowed | O browser não permite o serviço de voz pedido | A mesma mensagem que em not-allowed |
language-not-supported | O idioma não é suportado | Tentar de novo sem processLocally ou esconder o botão nesta língua |
phrases-not-supported | O modelo não consegue aplicar frases de contexto | Retirar a lista phrases e tentar de novo |
Em que difere o nosso componente de produção do exemplo mínimo
O SearchInput.astro em produção vai além do excerto acima, e cada diferença resultou do uso real:
- Resultados intermédios ativos: define
continuous = trueeinterimResults = true, escreve cada transcrição parcial no campo enquanto o utilizador fala e só envia quando chega um resultado comisFinaligual atrue. O utilizador vê as palavras a aparecer em vez de esperar em silêncio. - Paragem explícita: depois do resultado final chama
recognition.stop()e envia o formulário 500 ms depois. - Botão alternável: um segundo clique no microfone para a escuta. Uma flag
isListeningregista o estado. - Arranque protegido:
start()está dentro detry/catch, porque a especificação lança umInvalidStateErrorquando já há uma sessão a decorrer. - Triagem de erros:
no-speeché ignorado,abortedé silencioso,not-allowedmostra um placeholder traduzido de “microfone bloqueado”, qualquer outro código mostra um erro genérico de microfone, e o placeholder original volta ao fim de 3 segundos. - Textos traduzidos: os textos de escuta, bloqueio e erro existem nas seis línguas do site e chegam ao script através de atributos
data-no botão.
Como adicionar pesquisa por voz a um tema WordPress
O mesmo script funciona num tema WordPress clássico, porque a pesquisa do WordPress é um formulário GET comum. get_search_form() procura primeiro searchform.php no tema filho ou no tema pai e carrega-o; se não existir, imprime o formulário por omissão, cuja versão HTML5 é um <form role="search"> que envia para home_url( '/' ) com um campo chamado s (developer.wordpress.org). Dois hooks alteram-no sem template: o filtro get_search_form para o HTML e search_form_format para o formato.
A integração tem, portanto, três partes:
- Adicionar um
<button type="button">com uma etiqueta acessível junto ao camposemsearchform.php, escondido por omissão. - Apontar o script para esse campo e chamar
form.submit()depois do resultado final. A consulta chega à página normal de resultados de pesquisa, por isso nada muda no servidor. - Carregar o script com
wp_enqueue_script()e passararray( 'strategy' => 'defer', 'in_footer' => true )como quinto argumento. Desde o WordPress 6.3, esse argumento aceita um array com a chavestrategycom o valordeferouasync(developer.wordpress.org), por isso o código de voz nunca bloqueia a renderização.
Passe os textos traduzidos de “A ouvir…” e de erro com wp_localize_script() ou com atributos data- gerados através de esc_attr__(), para que o botão fale a mesma língua que o tema.
Como desenhar UX de pesquisa por voz no WordPress
A voz é invisível. Sem um ecrã, o utilizador não tem “cursor” para saber onde está. Portanto, o feedback da UI é crítico para fazer a ponte entre a intenção humana e a execução da máquina.
Como mostrar que o microfone está a ouvir
Quando o utilizador clica no microfone, a interface deve responder imediatamente.
- Animação de Pulso: Aplicámos uma classe CSS
animate-pulseao ícone do microfone. Um indicador vermelho ou pulsante é um significante universal para “A Gravar”. - Feedback de Placeholder: O texto de entrada muda para “A ouvir…”. Isto confirma que o sistema está pronto para entrada, impedindo o utilizador de falar demasiado cedo.
A especificação acrescenta dois requisitos obrigatórios do lado do browser. Uma sessão de reconhecimento só pode começar depois de um consentimento explícito e informado do utilizador, como um clique num controlo de voz claro, e o browser tem de mostrar um indicador evidente enquanto grava áudio, que também permita ao utilizador parar a gravação. O seu ícone pulsante complementa esse indicador, não o substitui.
Porque atrasar o envio da pesquisa reconhecida
Implementámos um atraso de 500ms entre capturar o texto e enviar o formulário.
- Porquê? Dá ao utilizador uma fração de segundo para ver o que a IA ouviu.
- Confiança: Se a IA ouviu mal “WordPress” como “Word Press”, ver o texto permite ao utilizador confiar que o sistema está a funcionar, mesmo que o resultado seja ligeiramente impreciso.
Acessibilidade da pesquisa por voz
A pesquisa por voz deve complementar a pesquisa por texto, nunca substituí-la. Utilizadores com dificuldades de fala ou de audição, ou em ambientes ruidosos, precisam que o campo de texto normal funcione sem atrito. O botão de voz só aparece quando o browser suporta a API, tem um aria-label, e a pesquisa por texto mantém-se intacta em todos os casos.
Como ler as respostas em voz alta com síntese de voz
A segunda metade da API trata da saída. window.speechSynthesis devolve o controlador SpeechSynthesis, que a especificação define como a API web programável para controlar uma saída de texto para voz. Coloca objetos SpeechSynthesisUtterance numa fila e fala-os por ordem, com speak(), cancel(), pause(), resume() e getVoices(). O suporte é muito mais amplo do que para o reconhecimento: Chrome 33, Edge 14, Firefox 49 e Safari 7, segundo o browser-compat-data.
function speak(text: string) {
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = document.documentElement.lang || 'pt-PT';
speechSynthesis.cancel(); // descartar o que ainda estiver na fila
speechSynthesis.speak(utterance);
}Há uma armadilha: no Chrome, a lista de vozes é preenchida de forma assíncrona. O MDN recomenda chamar getVoices() uma vez e de novo no evento voiceschanged, porque browsers mais antigos devolvem a lista de imediato, enquanto o Chrome precisa primeiro do evento. Um botão “ler o primeiro resultado em voz alta” construído assim fecha o ciclo de voz sem qualquer código no servidor.
O que a Google suporta realmente com speakable schema
Esta funcionalidade é, antes de mais, uma questão de experiência do utilizador. Do lado da pesquisa, a marcação relevante é speakable.
A pesquisa por voz ajuda o E-E-A-T
Implementar APIs atuais do browser demonstra Especialização técnica (o ‘E’ em E-E-A-T) a quem usa o site. A Google não documenta a entrada por voz como fator de classificação, por isso trate-a como uma funcionalidade de usabilidade e não como uma alavanca de SEO.
Como combinar pesquisa por voz com speakable schema
O Schema.org define speakable como uma propriedade de Article e WebPage que indica as secções de uma página web particularmente adequadas para serem faladas, apontando-as com seletores CSS ou XPaths dentro de uma SpeakableSpecification (schema.org). A documentação da Google reduz bastante o valor prático:
- A funcionalidade “está em beta e sujeita a alterações” (tradução própria).
- Funciona para utilizadores nos EUA com dispositivos Google Home configurados em inglês, e só para editores que publicam conteúdo em inglês.
- O Google Assistant usa-a para responder a pesquisas sobre notícias da atualidade em colunas inteligentes.
- A Google recomenda cerca de 20 a 30 segundos de áudio, aproximadamente duas a três frases, por secção speakable, e
cssSelectorouxPath, nunca os dois (Google Search Central).
Combinamos a entrada por voz com marcação speakable nos nossos artigos porque custa um bloco de frontmatter, mas não esperamos que a Google leia em voz alta um artigo que não é noticioso. O lado SEO completo da voz, incluindo featured snippets e marcação FAQ, está no nosso guia de SEO para pesquisa por voz.
O que vem depois da pesquisa por voz num site
Esta implementação representa a Fase Um da interação moderna com IA.
- Fase Um (Atual): Comando Voz-para-Texto. O utilizador fala, o site executa uma pesquisa baseada em texto.
- Fase Dois (Seguinte): Interfaces Conversacionais. O site usa um LLM (como a Realtime API da OpenAI) para entender a intenção e “desenhar” uma UI personalizada em resposta.
Por exemplo, em vez de pesquisar por “Preços”, um utilizador pode dizer: “Mostra-me planos para uma pequena agência.” O site renderizaria então dinamicamente uma tabela de comparação filtrada para essa necessidade específica.
Para chegar à Fase Dois, deve dominar a Fase Um. O Voice Search Nativo que construo hoje é a fundação para a Web Multimodal de amanhã.
É rápido, não envia código de terceiros e, com processLocally, pode manter a fala no dispositivo nos browsers que o suportam.
Veja os nossos serviços de otimização de velocidade WordPress.







