Search topics
Fields that submit on Enter during IME conversion
A shop's search box runs the search on any Enter keydown, so the Enter that confirms a Japanese conversion searches for a half-typed query.
if (event.key === 'Enter') search(input.value); The problem
People typing Japanese or Chinese through an input method have their search run, or their message sent, while they are still typing it.
A homewares shop has a search box in its header. The search runs from a keydown handler: when the key is Enter, it loads the results page. A visitor shopping in Japanese wants a folding umbrella, and starts to type 傘 折りたたみ ("umbrella, folding"). Japanese is typed through an input method editor, or IME. The visitor types かさ in kana, presses Space to see the kanji that match, picks 傘 from the list, and presses Enter to confirm it. Until that Enter, the word is a draft the IME is still working on, drawn underlined in the field; this is called composition. The Enter is meant for the IME, but the page's handler sees it too, and on a Mac, in Chrome and in Safari, its key is "Enter". The results page for 傘 loads before the second word is typed. Every word that needs converting does the same, so a search for two words runs once for each word, each time before the visitor has finished.
The same handler fails wherever Enter does something in script:
- A chat or comment box where Enter sends and Shift + Enter starts a new line: the message goes out at the first confirmed word.
- A suggestion list, where Enter picks the highlighted suggestion: the confirming Enter puts the suggestion in the field in place of the word being typed. See autocomplete fields with silent, mouse-only suggestions for the rest of that pattern.
- A form that moves to the next field on Enter: the cursor jumps away in the middle of a name or an address.
An IME turns key presses into text, and its Enter is one of those presses. Success Criterion 2.1.1 asks that all functionality be operable through a keyboard interface. Typing into a field is functionality, and here the field takes part of the typing as a command, so text that needs a conversion can't be typed into it in one go. Success Criterion 3.2.2 says that changing a component's setting must not cause a change of context, such as a new page, unless people were told beforehand, and its Understanding document counts entering text into a text field as changing its setting. The confirming Enter is part of entering the text, and it loads a new page. The closest failure W3C documents is F36: a form that submits by itself, without warning, while someone is still entering values, rather than through the standard behaviour of a submit button and the Enter key, which F36 says to rely on. The confirming Enter is not that standard behaviour: the browser's own form doesn't submit on it.
Neither criterion names IMEs, and an author could argue that any Enter is a request to submit. This guide reads it the other way: the person pressed Enter to tell the IME they had chosen a word, the browser itself doesn't submit a form on that Enter, and the handler can tell the difference with one line. Where the Enter sends a message rather than loading a page, it is not a change of context, and 2.1.1 carries it alone.
Everyone who types Japanese or Chinese through an IME meets this every time they type into such a field, whatever their abilities. The groups below are the people for whom it costs the most.
3 of 10 groups affected
- No vision (affected)
- Low vision (not affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Limited manipulation People who type slowly, with one hand, a mouth stick or an on-screen keyboard spend many presses on every word. A search that runs at the first confirmed word sends them back to the field to find the end of the text and type the rest, and the next word does it again.
- Limited language, cognitive and learning abilities A search that runs before the query is finished looks as if the site misread them. Nothing connects it with the Enter they pressed for the conversion, so it is hard to tell what went wrong or how to avoid it.
- Without vision A screen reader user confirming a word hears the results page start reading from the top, and has to work out that the query was cut short, then find the search field again.
The markup is a labelled search field, so a scan finds nothing. A scan doesn't type, and someone testing without an IME never starts a composition, so the confirming Enter never happens. Even a developer who uses an IME may miss it: Chrome on Windows and Firefox are documented to report this Enter's key as "Process", so the bug shows on a Mac first. AI assistants asked to "search when Enter is pressed" often write the Before below. EaseWeb's audit types a conversion into up to eight text fields of a page with scripted composition events, presses Enter as Chrome and as Safari send it, and reports a field whose page submits, loads another page, sends a request, clears the field or moves focus on that Enter. It can't see a handler that reacts only to real key presses, or a field it can't type into, such as a rich text editor.
Try it
Type a word that needs converting with the Japanese input above the window, then press Enter in the field to search.
The Enter that confirms 傘 is meant for the IME. Watch whether the page searches on it, and what the page got. With a Japanese IME of your own, type in the field for real.
Broken Can you fix this?
Linden Home
Ready for the rainy season
Umbrellas, boots and covers for every day.
Enter, as the page got it: none yet
The fix
Let the form handle Enter, or skip the Enter that confirms a conversion.
- 1Submit a field from its form, or skip Enter while
isComposingis true orkeyCodeis 229. - 2Act on Enter on keydown, never on keyup.
- 3Test with a real IME, in Safari as well as Chrome.
<div role="search"> <label for="q">Search</label> <input id="q" type="search"></div> <script> const input = document.getElementById('q'); input.addEventListener('keydown', (event) => { if (event.key === 'Enter') search(input.value); }); function search(query) { location.assign(`/search?q=${encodeURIComponent(query)}`); }</script>A form, so the browser decides
<form role="search" action="/search"> <label for="q">Search</label> <input id="q" name="q" type="search"></form>Why this fix: Use native HTML first
The handler acts on every Enter, including the one that confirms a conversion. Nothing in it asks whether the IME is still composing.
The search box is a form, and the browser submits it on Enter, which is called implicit submission. Chrome, Safari and Firefox submit from the Enter key's keypress event, and the UI Events specification says keypress must not be fired when an IME is in use, so the Enter that confirms a conversion only confirms it. The next Enter submits. A form with a single text field submits on Enter even without a button, but a Search button helps people who don't know that. On a single-page site, listen for the form's submit event, call preventDefault() and load the results in script: the browser still decides which Enter submits.
Both pass. Use the form for a field whose Enter submits it, such as a search box or a sign-up field: it needs no script, doesn't depend on a deprecated property, and keeps working as browsers change how they order these events. Use the keydown check where Enter has another job, or isn't the only key handled: a textarea, a chat composer or a combobox, where a form can't do the work. A site usually needs both, each in its place.
Keep both halves of the check. WebKit bug 165004, filed in 2016, records Safari's order on macOS: compositionend before the keydown. WebKit switched to the specified order in April 2026 and switched it off again in June after regression reports, so Safari still sends the confirming Enter with isComposing false. The keyCode half costs nothing where isComposing already catches the press. Don't test for a key of "Process" instead: Chrome on a Mac and Safari report "Enter".
A flag set on compositionstart and cleared on compositionend is not enough on its own. In Safari, compositionend comes before the confirming keydown, so the flag is already cleared when the Enter arrives.
Act on Enter on keydown, not keyup. The confirming Enter's keyup comes after compositionend, with isComposing false, and MDN notes that keyup has no special keyCode for IME events, so nothing tells it apart from an Enter meant to submit.
In a suggestion list, the same check keeps the arrow keys for the IME. While a word is being converted, the up and down arrows move through the IME's candidates, and a combobox handler that moves its own highlight on them confuses both lists.
In a framework, put the same check in the handler you give the field. Component libraries with their own Enter handling, such as chat inputs and tag inputs, need the same test with a real IME before you rely on them.
Fixing this with an AI coding assistant? Get this guide as Markdown, or get every guide in your coding agent.
Verify the fix
5 checks, no mouse.
Test with: Keyboard, Input method (IME), Screen reader
Record the OS, browser, input method and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after a search, chat or form component changes.
Limits
This is a starting pattern, not a guarantee for every application. The example is one search field typed in Japanese; Chinese input methods confirm text in their own ways. Korean ones usually pass the Enter that ends a syllable on as an ordinary Enter, and reports differ on whether Safari sends it with keyCode 229 or 13, so the second fix may swallow an Enter a Korean typist meant; test Korean input in Safari if your customers use it. Phone keyboards send their own sequence of events, so test with the input methods your customers use. Rich text editors handle composition themselves and need their own testing. The snippets leave out the search itself.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
References
- WCAG Understanding: keyboard (opens in a new tab)
- WCAG Understanding: on-input (opens in a new tab)
- WCAG Technique F36 (opens in a new tab)
- w3c.github.io: uievents (opens in a new tab)
- developer.mozilla.org: keydown_event (opens in a new tab)
- developer.mozilla.org: isComposing (opens in a new tab)
- html.spec.whatwg.org: form-control-infrastructure (opens in a new tab)
- bugs.webkit.org: show_bug.cgi (opens in a new tab)
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.