DEV Community

Cover image for Improving Japanese Input UX in Multilingual Applications: Properly Handling IME Conversion
s4yuba
s4yuba

Posted on

Improving Japanese Input UX in Multilingual Applications: Properly Handling IME Conversion

Introduction

In global web application development, multilingual support is an essential requirement. However, languages that use IME (Input Method Editor) such as Japanese, Chinese, and Korean have unique input and conversion processes that require special consideration. This article explains issues with form operations in Japanese input and their solutions.

Target Audience

  • Web application developers
  • Frontend developers
  • Those involved in developing globally accessible applications

The Problem: Event Handling During IME Conversion

Japanese input involves a conversion process from "hiragana" to "katakana/kanji". During this process, the following issue often occurs:

Image description

Example: When trying to search for "Tokyo Tower"
1. Type "とうきょうたわー" (hiragana)
2. Press spacebar to display conversion candidates
3. Press Enter to confirm "東京タワー" (kanji/katakana)
4. This Enter key mistakenly triggers the search execution
Enter fullscreen mode Exit fullscreen mode

This results in an unintended search for "Tokyo Tower" and degrades the user experience. This problem is particularly noticeable in UIs where the Enter key executes actions, such as search forms and chat interfaces.

Technical Background: Composition Events

When inputting with IME, "Composition" events occur in addition to standard keyboard events:

  • compositionstart: Start of conversion process
  • compositionupdate: Update of text during conversion
  • compositionend: End of conversion process

Additionally, the KeyboardEvent object includes an isComposing property that indicates whether IME conversion is in progress. Understanding this characteristic is the first step toward improving UX.

Solution: Using the isComposing Property

IME support can be implemented in frontend frameworks like React, Vue, and Angular as follows:

React Implementation Example

function SearchField({ onSearch }) {
  const handleKeyDown = (event) => {
    // Ignore Enter during IME conversion confirmation
    if (event.key === "Enter" && !event.nativeEvent.isComposing) {
      event.preventDefault();
      const searchTerm = event.target.value.trim();
      if (searchTerm) {
        onSearch(searchTerm);
      }
    }
  };

  return (
    <input 
      type="text" 
      onKeyDown={handleKeyDown} 
      placeholder="Search..." 
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

Vue Implementation Example

<template>
  <input 
    type="text" 
    @keydown="handleKeyDown" 
    placeholder="Search..." 
  />
</template>

<script>
export default {
  methods: {
    handleKeyDown(event) {
      if (event.key === "Enter" && !event.isComposing) {
        event.preventDefault();
        const searchTerm = event.target.value.trim();
        if (searchTerm) {
          this.$emit('search', searchTerm);
        }
      }
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

HTML/JavaScript Implementation Example

document.querySelector('input').addEventListener('keydown', function(event) {
  if (event.key === 'Enter' && !event.isComposing) {
    event.preventDefault();
    const searchTerm = this.value.trim();
    if (searchTerm) {
      performSearch(searchTerm);
    }
  }
});
Enter fullscreen mode Exit fullscreen mode

Handling More Complex UI Components

The same approach can be applied when using UI libraries like Material-UI, Ant Design, and Chakra UI. Here's an implementation example with Material-UI's Autocomplete component:

import { Autocomplete, TextField } from '@mui/material';

function SearchComponent({ onSearch, options }) {
  const [inputValue, setInputValue] = useState('');

  const handleKeyDown = (event) => {
    if (event.key === 'Enter' && !event.nativeEvent.isComposing) {
      event.preventDefault();
      if (inputValue.trim()) {
        onSearch(inputValue.trim());
      }
    }
  };

  return (
    <Autocomplete
      freeSolo
      options={options}
      inputValue={inputValue}
      onInputChange={(event, newValue) => setInputValue(newValue)}
      renderInput={(params) => (
        <TextField
          {...params}
          label="Search"
          variant="outlined"
          onKeyDown={handleKeyDown}
        />
      )}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

Testing Methods

To test IME-related implementations:

  1. Operate the application in Japanese input mode
  2. Enter "hiragana" and display conversion candidates
  3. Press Enter to confirm the conversion
  4. Verify that pressing Enter again executes the search

It's ideal to test in a Japanese environment, but if Japanese IME is not available in your development environment, the following tools can be helpful:

  • Windows: Microsoft IME
  • macOS: Japanese Input System
  • Online emulators: Some browser extensions can simulate IME input

Browser Compatibility Notes

While the isComposing property is widely supported in modern browsers, it may behave differently in older browsers. As an alternative approach to ensure compatibility, consider implementing using compositionstart and compositionend events:

let isComposing = false;

input.addEventListener('compositionstart', () => {
  isComposing = true;
});

input.addEventListener('compositionend', () => {
  isComposing = false;
});

input.addEventListener('keydown', (event) => {
  if (event.key === 'Enter' && !isComposing) {
    // Execute search process
  }
});
Enter fullscreen mode Exit fullscreen mode

Conclusion

In multilingual applications, input processing that considers IME is essential. Especially in cases where the Enter key executes actions such as in search forms and chat interfaces, it's important to use the isComposing property to distinguish between IME conversion processes and normal input.

This small consideration greatly improves the experience for users of languages such as Japanese, Chinese, and Korean. In global application development, attention to such details leads to true multilingual support.

References

Top comments (0)