IME操作中のEnterキーでフォームが誤送信される問題を検出するESLintプラグインを作った話
公開日:
- #JavaScript
- #ESLint
- #IME
- #アクセシビリティ
日本語などのIME(Input Method Editor)を利用するユーザが、たびたび遭遇する不具合があります。まだ入力中なのに送信されてしまうというアレです。
この件について大変わかりやすいスライドで問題提起をしている、かみくずさんのツイートを拝見しまして、ESLintのプラグイン eslint-plugin-ime-safe-form を用意しました。
世界中のWebフロントエンドエンジニアに届いてほしいのですが
— かみくず (@p_craft) April 15, 2026
keydownイベントでEnterキーを待ち受けてサブミットを行う機能を作るとき、KeyboardEvent.isComposingを参照してください。そうしないと日本人ユーザーがまともに使えなくなります。
詳しくはこちらを。https://t.co/Vx0PbtZqmb
問題となる実装の具体例
keydownイベントでEnterキーが押された時にフォームを送信するような実装です[1]。
inputElement.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
submit();
}
});IMEユーザは変換を確定するためにもEnterキーを押します。「Enterキーが押された時」だけでハンドリングしてしまうと、変換を確定しようとしただけなのにフォームが送信されてしまうわけです。
この問題は日本語利用者だけでなく、中国語・韓国語・ベトナム語・タイ語などIMEを使う数十億人のユーザに影響する問題です。
正しい実装
筆者個人としては、form要素のsubmitイベントを使う方法を推奨しています。こうしておけばそもそもIMEのサポートを考えなくてよくなります。
formElement.addEventListener('submit', (event) => {
event.preventDefault();
submit();
});一方で、送信する以外の目的でkeydownイベントによって何かを実行する場合には、KeyboardEvent.isComposingを確認する必要があります。
inputElement.addEventListener('keydown', (event) => {
if (event.isComposing || event.keyCode === 229) {
return;
}
if (event.key === 'Enter') {
submit();
}
});なお、event.keyCode === 229はSafariのバグを回避するためのものです[2]。
ESLintプラグイン
普段IMEを利用しているなら別ですが、英語圏などの非IMEユーザがこの問題に気づくのは難しいでしょう。というわけでESLintプラグインを用意しました。
npm install --save-dev eslint-plugin-ime-safe-formimport imeSafeForm from "eslint-plugin-ime-safe-form";
export default [
{
plugins: {
"ime-safe-form": imeSafeForm,
},
rules: {
"ime-safe-form/no-enter-keydown-without-composition-check": "error",
},
},
];設定すると、vanilla/JSXともにisComposing未使用を検出できます。
inputElement.addEventListener('keydown', (event) => {
if (event.key === 'Enter') submit();
});
<input onKeyDown={(event) => {
if (event.key === 'Enter') submit();
}} />inputElement.addEventListener('keydown', (event) => {
if (event.isComposing || event.keyCode === 229) return;
if (event.key === 'Enter') submit();
});
<input onKeyDown={(event) => {
if (event.isComposing || event.keyCode === 229) return;
if (event.key === 'Enter') submit();
}} />終わりに
eslint-plugin-ime-safe-formを導入することで、isComposingのチェック漏れを検出できるようになります。
すでにIssueを立てていただいておりますが、今後はTab・Escapeへの対応なども追加していけたらと思います。
まだ改善の余地はありますが、IMEユーザの体験改善につながる議論が進んでいけば嬉しいです。
また、Biomeにも同様のルールが提案されており、そこでこのプラグインを根拠に添えていただきました。
無事に組み込まれることで、IMEユーザの困った!が少しでも減ることに期待したいです。
脚注
- [^1]:
keydownのみならず、keypress(非推奨)やkeyupなども同様の問題が発生する。 - [^2]:古いSafariでは
compositionendイベントがkeydownより先に発火してしまう。IME変換中はkeyCodeが常に229になるという仕様を利用することで、Safariでも正しく判定できる。参考:Element: keydown event - MDN