Tastingens æra nærmer seg slutten. Som diskutert i vår Voice Search SEO Guide, har brukeratferd endret seg fundamentalt innen 2026. “Tastatur-først” design er i ferd med å bli et foreldet konsept.
Med fremveksten av “Ambient AI”, der datamaskiner er allestedsnærværende lyttere snarere enn bare skjermer, er forventningen til multimodal interaksjon (stemme, gest, blikk) standard. Brukere vil ikke skrive “WordPress utvikler Warszawa”; de vil spørre: “Finn meg en WordPress-ekspert i nærheten.”
Mens AI-avatar-widgets gjengir imponerende 3D-samtaleavatarer, mener vi det første kritiske steget for de fleste høyytelses WordPress-sider er et lett, effektivt og native grensesnitt for talesøk.
Denne casestudien dokumenterer hvordan vi bygget talesøkknappen i søkefeltet på wppoland.com: null plugins, null bloat, ren JavaScript. Den dekker den tekniske implementeringen, hvor lyden faktisk havner, hvilke nettlesere som støtter det i oktober 2026, og hvorfor vi valgte denne veien fremfor tunge tredjeparts widgets.
Hvorfor AI-avatar-widgets svekker Core Web Vitals
Før vi valgte native talesøk, sammenlignet vi det med innebygde “AI Avatar”-widgets.
Hvordan AI-avatar-widgets gjør LCP og INP tregere
Samtaleavatarer er visuelt imponerende. De bruker WebGL til å rendre livaktige ansikter som synkroniserer leppebevegelser med AI-generert lyd. Men for en bedriftsnettside eller en portefølje med høy ytelse, introduserer de betydelig “ytelsesgjeld”:
- LCP (Largest Contentful Paint): Lasting av en 3D-motor (som Three.js) og karakter-ressurser blokkerer ofte hovedtråden og forsinker LCP.
- INP (Interaction to Next Paint): Konstante animasjonsløkker og hendelseslyttere kan forårsake mikrohakking ved scrolling eller klikking.
- Personvern-overhead: Sending av kontinuerlige lydstrømmer til en tredjepartsserver øker GDPR-samsvarshinderne.
Vårt mål: Muliggjøre “Ambient AI”-interaksjon, la brukere snakke til nettsiden naturlig, uten å ofre vår PageSpeed-score eller legge til enda et tredjepartsskript.
Web Speech API for talesøk i nettleseren
Chrome, Edge og Safari har et grensesnitt som mange utviklere overser: Web Speech API. Det har to halvdeler. SpeechRecognition gjør mikrofonlyd om til tekst, og SpeechSynthesis gjør tekst om til tale. Spesifikasjonen er en Draft Community Group Report som vedlikeholdes i repositoriet til W3C Audio Community Group, ikke en W3C-anbefaling, og MDN merker SpeechRecognition som “Limited availability”, altså ikke Baseline.
- Ingen eksterne biblioteker: Gjenkjenningsmotoren leveres av nettleseren, så den eneste koden du sender ut er limet mellom API-et og søkeskjemaet.
- Ingen leverandøravtale: Du registrerer deg ikke for et tale-til-tekst-API og håndterer ingen nøkler.
- Ikke alltid lokalt: Gjenkjenningen kjører der nettleseren bestemmer. Neste avsnitt forklarer hvorfor det betyr noe.
Web Speech API vs. AI-avatar-widget
| Funksjon | Native Web Speech API | Ekstern AI-widget |
|---|---|---|
| Pakkestørrelse | 0kb bibliotek (native i nettleser) | Leverandørskript, 3D-motor og karakterressurser |
| Personvern | Nettleserleverandørens tjeneste som standard, på enheten ved forespørsel | Widgetleverandørens sky |
| Ytelse | Ingenting lastes før brukeren trykker på mikrofonen | Høy CPU-bruk |
| Integrasjon | Egen kode (<50 linjer) | Drop-in-skript |
| Kostnad | Gratis | Leverandørens prismodell |
| Visuelt | Usynlig (UI-styrt) | 3D-avatar |
For wppoland.com var valget klart: ytelse er vår merkevare. Vi valgte native.
Hvor Web Speech API sender stemmelyden
Web Speech API lover ikke lokal behandling. MDNs veiledning til API-et er tydelig: “Som standard innebærer talegjenkjenning på en nettside en serverbasert gjenkjenningsmotor. Lyden din sendes til en nettjeneste for gjenkjenning, så den fungerer ikke offline.” (MDN, Using the Web Speech API, egen oversettelse). I Chrome tilhører den nettjenesten nettleserleverandøren, ikke deg og ikke en pluginutvikler.
Spesifikasjonen tilbyr nå et alternativ du må velge aktivt. Når recognition.processLocally = true settes før start(), angir det et krav om at gjenkjenningen skjer på enheten. Modusen på enheten trenger en språkpakke per språk. Mangler pakken, feiler start() med feilen language-not-supported. To statiske metoder håndterer pakkene:
SpeechRecognition.available({ langs, processLocally })returnererunavailable,downloadable,downloadingelleravailable.SpeechRecognition.install({ langs })laster ned pakkene og returnerertrueellerfalse.
Begge metodene styres av Permissions-Policy-direktivet on-device-speech-recognition, med standard tillatelsesliste self, så en iframe fra et annet opphav kan ikke kalle dem med mindre foreldresiden delegerer funksjonen.
For et nettsted med besøkende fra EU er den praktiske konsekvensen enkel: en stemmeknapp i standardmodus sender tale til nettleserleverandørens gjenkjenningstjeneste, og personvernerklæringen din bør si det med rene ord. Påstanden vår om “personvern først” holder bare i den smalere betydningen at ingen tredjeparts plugin eller widgetleverandør mottar lyden.
Slik ber du om gjenkjenning på enheten med reserveløsning
const SR = window.SpeechRecognition || window.webkitSpeechRecognition;
const lang = document.documentElement.lang || 'nb-NO';
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; // lyden blir på enheten
} else if (status === 'downloadable') {
// Tilby nedlastingen fra en brukerhandling; ellers bruk servermotoren
}
}MDN påpeker at implementasjoner som støtter gjenkjenning på enheten gjør det uten prefiks, så available() finnes bare på den uprefiksede konstruktøren. Sjekk at den finnes, anta det aldri.
Hvilke nettlesere støtter Web Speech API i 2026
Tabellen under kommer fra MDNs browser-compat-data, versjon 8.1.6 (15. oktober 2026). Versjonsnumrene er første utgivelse med støtte.
| Nettleser | SpeechRecognition | På enheten (processLocally, available(), install()) | SpeechSynthesis |
|---|---|---|---|
| Chrome (desktop og Android) | 139 uten prefiks, 33 som webkitSpeechRecognition | 139 (eksperimentell) | 33 |
| Edge | 139 uten prefiks, 79 med prefiks | 139 (eksperimentell) | 14 |
| Safari (macOS) | 14.1, kun med webkit-prefiks | Ikke støttet | 7 |
| Safari (iOS) | 14.5, kun med webkit-prefiks | Ikke støttet | 7 |
| Firefox | Kun forhåndsversjoner | Kun forhåndsversjoner | 49 |
| Samsung Internet | 30.0 uten prefiks, 2.0 med prefiks | Ikke oppført | 3.0 |
Tre konklusjoner følger for et WordPress-tema. Behold reserveløsningen window.SpeechRecognition || window.webkitSpeechRecognition, fordi Safari fortsatt bare har navnet med prefiks. Skjul mikrofonknappen når ingen av konstruktørene finnes, ellers ser Firefox-brukere en knapp som ikke gjør noe. Behandle gjenkjenning på enheten som en bonus som foreløpig bare finnes i Chromium.
Slik lager du talesøk med JavaScript
Vi la denne funksjonaliteten til vår SearchInput.astro-komponent. Dette sikrer at søkefeltet er den eneste sannhetskilden for både tekst- og talehenvendelser.
Trinn 1: Funksjonsdeteksjon
Først må vi respektere brukerens nettleseregenskaper. Vi antar aldri at et API eksisterer.
// Sjekk om nettleseren støtter SpeechRecognition
if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
const voiceBtn = document.getElementById("voice-search-btn");
voiceBtn.classList.remove("hidden"); // Vis kun knapp hvis støttet
}Trinn 2: Kode for talegjenkjenning
Her er en forenklet versjon av koden. Legg merke til reserveløsningen med webkit-prefikset: Chromium-nettlesere godtar navnet uten prefiks fra versjon 139, men Safari eksponerer fortsatt bare webkitSpeechRecognition.
// 1. Initialiser
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const recognition = new SpeechRecognition();
// 2. Konfigurasjon
recognition.continuous = false; // Stopp etter én setning
recognition.interimResults = false; // Returner kun endelige resultater
recognition.lang = document.documentElement.lang || 'nb-NO'; // Dynamisk språkstøtte
// 3. Hendelseshåndterere
recognition.onstart = () => {
// Visuell feedback er avgjørende for Voice UI
voiceBtn.classList.add("text-red-500", "animate-pulse");
searchInput.placeholder = "Lytter...";
};
recognition.onend = () => {
// Rydd opp UI-tilstand
voiceBtn.classList.remove("text-red-500", "animate-pulse");
searchInput.placeholder = "Søk...";
};
recognition.onresult = (event) => {
// 4. Fang transkripsjon
const transcript = event.results[0][0].transcript;
searchInput.value = transcript;
// 5. UX: Auto-send etter en naturlig pause
// Dette fjerner friksjonen ved å klikke "Søk" igjen
setTimeout(() => searchInput.form.submit(), 500);
};
// 6. Utløser
voiceBtn.addEventListener('click', () => recognition.start());Hvis du lar lang stå tom, faller spesifikasjonen tilbake på språket til dokumentets rotelement, så et korrekt <html lang>-attributt gir allerede hver språkversjon riktig gjenkjenningsspråk.
Trinn 3: Feilhåndtering
Bruk i den virkelige verden er rotete. Brukere nekter mikrofontilgang, eller bakgrunner er støyende. Vi la til feilhåndtering for å falle elegant tilbake til tekstinntasting hvis mikrofonen er blokkert.
recognition.onerror = (event) => { console.log('Stemmefeil:', event.error); };
Hvilke feil i talegjenkjenningen du bør håndtere
Hendelsen error bærer én av åtte koder definert i spesifikasjonen. Hver krever en egen reaksjon:
| Feilkode | Hva spesifikasjonen sier | Fornuftig reaksjon |
|---|---|---|
no-speech | Ingen tale ble oppdaget | Ignorer eller nullstill stille, brukeren sa rett og slett ingenting |
aborted | Taleinndata ble avbrutt, for eksempel av brukeren | Nullstill grensesnittet uten melding |
audio-capture | Lydopptak mislyktes | Vis en mikrofonfeil |
network | Nødvendig nettverkskommunikasjon mislyktes | Foreslå å skrive i stedet, servermotoren er utilgjengelig |
not-allowed | Blokkert av sikkerhets-, personvern- eller brukerinnstillingsgrunner | Fortell brukeren at mikrofonen er blokkert i nettleserinnstillingene |
service-not-allowed | Nettleseren tillater ikke den forespurte taletjenesten | Samme melding som for not-allowed |
language-not-supported | Språket støttes ikke | Prøv igjen uten processLocally eller skjul knappen for denne språkversjonen |
phrases-not-supported | Modellen kan ikke bruke kontekstuelle fraser | Fjern phrases-listen og prøv igjen |
Hvordan produksjonskomponenten vår skiller seg fra minimumseksempelet
Den levende SearchInput.astro går lenger enn kodebiten over, og hver forskjell kom fra reell bruk:
- Foreløpige resultater på: den setter
continuous = trueoginterimResults = true, skriver hver delvise transkripsjon inn i feltet mens brukeren snakker, og sender først når et resultat kommer medisFinalsatt tiltrue. Brukeren ser ordene dukke opp i stedet for å vente i stillhet. - Eksplisitt stopp: etter det endelige resultatet kaller den
recognition.stop(), og sender deretter skjemaet etter 500 ms. - Av/på-knapp: et nytt klikk på mikrofonen stopper lyttingen. Et
isListening-flagg holder styr på tilstanden. - Beskyttet start:
start()ligger inne itry/catch, fordi spesifikasjonen kasterInvalidStateErrornår en økt allerede kjører. - Sortering av feil:
no-speechignoreres,aborteder stille,not-allowedviser en lokalisert plassholder om blokkert mikrofon, alle andre koder viser en generell mikrofonfeil, og den opprinnelige plassholderen kommer tilbake etter 3 sekunder. - Lokaliserte tekster: lytte-, blokkerings- og feiltekstene finnes på alle seks språkene på nettstedet og sendes til skriptet gjennom
data--attributter på knappen.
Slik legger du talesøk til et WordPress-tema
Det samme skriptet fungerer i et klassisk WordPress-tema, fordi WordPress-søk er et vanlig GET-skjema. get_search_form() ser først etter searchform.php i child- eller parent-temaet og laster det; finnes det ikke, skriver den ut standardskjemaet, der HTML5-versjonen er et <form role="search"> som sender til home_url( '/' ) med et felt kalt s (developer.wordpress.org). To hooks endrer det uten mal: filteret get_search_form for HTML-en og search_form_format for formatet.
Integrasjonen har derfor tre deler:
- Legg til en
<button type="button">med tilgjengelig etikett ved siden avs-feltet isearchform.php, skjult som standard. - Pek skriptet mot det feltet og kall
form.submit()etter det endelige resultatet. Søket havner på den vanlige resultatsiden, så ingenting endres på serveren. - Last skriptet med
wp_enqueue_script()og sendarray( 'strategy' => 'defer', 'in_footer' => true )som femte argument. Siden WordPress 6.3 godtar det argumentet en array med nøkkelenstrategysatt tildeferellerasync(developer.wordpress.org), så talekoden blokkerer aldri renderingen.
Send de oversatte tekstene for lytting og feil med wp_localize_script() eller med data--attributter rendret gjennom esc_attr__(), slik at knappen snakker samme språk som temaet.
Slik designer du UX for talesøk
Stemme er usynlig. Uten en skjerm har brukeren ingen “markør” for å vite hvor de er. Derfor er UI-tilbakemelding avgjørende for å bygge bro mellom menneskelig intensjon og maskinell utførelse.
Hvordan vise at mikrofonen lytter
Når brukeren klikker på mikrofonen, må grensesnittet reagere umiddelbart.
- Puls-animasjon: Vi brukte en CSS
animate-pulse-klasse på mikrofonikonet. En rød eller pulserende indikator er en universell betegnelse for “Opptak”. - Plassholder-feedback: Teksten i feltet endres til “Lytter…”. Dette bekrefter at systemet er klart for input, og forhindrer at brukeren snakker for tidlig.
Spesifikasjonen legger til to harde krav på nettlesersiden. En gjenkjenningsøkt kan bare starte etter eksplisitt og informert samtykke fra brukeren, for eksempel et klikk på en tydelig talekontroll, og nettleseren må vise en tydelig indikator mens lyd tas opp, som også lar brukeren stoppe opptaket. Det pulserende ikonet ditt utfyller den indikatoren, det erstatter den ikke.
Hvorfor vente med å sende det gjenkjente søket
Vi implementerte en 500ms forsinkelse mellom fangst av teksten og sending av skjemaet.
- Hvorfor? Det gir brukeren en brøkdel av et sekund til å se hva AI-en hørte.
- Tillit: Hvis AI-en hørte “WordPress” feil som “Word Press”, lar teksten brukeren stole på at systemet fungerer, selv om resultatet er litt unøyaktig.
Tilgjengelighet i talesøk
Talesøk skal utfylle tekstsøk, aldri erstatte det. Brukere med tale- eller hørselsnedsettelser, eller i støyende omgivelser, trenger at det vanlige tekstfeltet fungerer uten friksjon. Stemmeknappen vises bare når nettleseren støtter API-et, har en aria-label, og tekstsøket forblir intakt i alle tilfeller.
Slik leser du søkesvar høyt med talesyntese
Den andre halvdelen av API-et dekker utdata. window.speechSynthesis returnerer kontrolleren SpeechSynthesis, som spesifikasjonen definerer som det skriptbare web-API-et for å styre tekst-til-tale-utdata. Den legger SpeechSynthesisUtterance-objekter i kø og leser dem i rekkefølge, med speak(), cancel(), pause(), resume() og getVoices(). Støtten er langt bredere enn for gjenkjenning: Chrome 33, Edge 14, Firefox 49 og Safari 7 ifølge browser-compat-data.
function speak(text: string) {
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = document.documentElement.lang || 'nb-NO';
speechSynthesis.cancel(); // forkast det som fortsatt står i kø
speechSynthesis.speak(utterance);
}En felle: i Chrome fylles stemmelisten asynkront. MDN anbefaler å kalle getVoices() én gang og på nytt ved hendelsen voiceschanged, fordi eldre nettlesere returnerer listen umiddelbart mens Chrome trenger hendelsen først. En knapp for “les første treff høyt” bygget slik gir en komplett stemmesløyfe uten serverkode.
Hva Google faktisk støtter med speakable schema
Denne funksjonen handler først om brukeropplevelse. På søkesiden er den relevante markeringen speakable.
Hjelper talesøk med E-E-A-T
Å implementere aktuelle nettleser-API-er viser teknisk ekspertise (‘E’-en i E-E-A-T) overfor menneskene som bruker nettstedet. Google dokumenterer ikke stemmeinndata som rangeringsfaktor, så behandle det som en brukervennlighetsfunksjon, ikke et SEO-verktøy.
Slik kombinerer du talesøk med speakable schema
Schema.org definerer speakable som en egenskap for Article og WebPage som angir deler av en nettside som er spesielt egnet for opplesning, og peker på dem med CSS-selektorer eller XPath inne i en SpeakableSpecification (schema.org). Googles dokumentasjon snevrer den praktiske verdien betydelig inn:
- Funksjonen er i beta og kan endres.
- Den fungerer for brukere i USA med Google Home-enheter satt til engelsk, og bare for utgivere som publiserer innhold på engelsk.
- Google Assistant bruker den til å svare på aktuelle nyhetsspørsmål på smarthøyttalere.
- Google anbefaler rundt 20 til 30 sekunder lyd, omtrent to til tre setninger, per speakable-del, og enten
cssSelectorellerxPath, aldri begge (Google Search Central).
Vi kombinerer stemmeinndataene med speakable-markering på artiklene våre fordi det koster én frontmatter-blokk, men vi forventer ikke at Google leser opp en artikkel som ikke er en nyhet. Hele SEO-siden av talesøk, inkludert fremhevede utdrag og FAQ-markering, finner du i vår guide til SEO for talesøk.
Hva kommer etter talesøk på nettsider
Denne implementeringen representerer trinn én av moderne AI-interaksjon.
- Trinn én (nåværende): Tale-til-tekst-kommando. Brukeren snakker, siden utfører et tekstbasert søk.
- Trinn to (neste): Konversasjonelle grensesnitt. Siden bruker en LLM (som OpenAIs Realtime API) for å forstå intensjon og “tegne” et tilpasset UI som respons.
For eksempel, i stedet for å søke etter “Priser”, kan en bruker si: “Vis meg planer for et lite byrå.” Siden ville da dynamisk rendre en sammenligningstabell filtrert for det spesifikke behovet.
For å komme til trinn to, må du mestre trinn én. Det native talesøket vi bygget i dag, er fundamentet for morgendagens multimodale web.
Det er raskt, sender ingen tredjepartskode, og med processLocally kan det holde talen på enheten i nettleserne som støtter det.







