Tuomas Siipola Articles Projects

Hyphenation in React Native

Hyphenation is the practise of breaking lines based on syllables to make the text flow better. This is widely used in print but isn't too common with user interfaces on the web or mobile. In many situations, hyphenation is not crucial, but especially with limited space and long words it can be indispensable to make text good-looking and easy to read.

React Native doesn't support hyphenation out of the box. Instead, line breaks are based on individual words. In case the word doesn't fit all in one line, it's split arbitrarily by character. This can make the text unnatural and difficult to read as seen here:

In order to hyphenate words correctly, we have to specify how to do this ourselves. This is done by inserting soft hyphens between syllables. Soft hyphens are invisible characters that mark possible locations in a word for a line break. Given this information, React Native can then do the line breaking properly where necessary.

In JSX (and HTML) soft hyphen is encoded as ­ entity:

<Text>
  Hy&shy;phen&shy;ation
</Text>

In JavaScript and JSON strings U+00AD code point can be used:

const text = 'Hy\u00ADphen\u00ADation';

Automatic hyphenation

Inserting soft hyphens by hand is tedious and doesn't work with dynamic text like user input or other external data. To overcome this, we can use a library like Hypher to automatically hyphenate any text. First, install the library alongside the necessary language data (see hyphenation-patterns for available languages):

npm install hypher hyphenation.en-us

Then hyphenate text as follows:

import Hypher from 'hypher';
import english from 'hyphenation.en-us';

const h = new Hypher(english);

<Text>
  {h.hyphenateText("Hyphenation")}
</Text>

We can even create a drop-in replacement for the standard Text component:

import Hypher from 'hypher';
import english from 'hyphenation.en-us';

const h = new Hypher(english);

const HyphenatedText = (props) => {
  <Text {...props}>
    {h.hyphenateText(props.children)}
  </Text>
};

export default HyphenatedText;

Fine-tuning

The hyphenation may require some fine-tuning depending on layout, available space and text content. Here's a couple of ways to control the hyphenation in Hypher.

Firstly, hyphenateText function takes an optional second parameter minLength which defines the minimum length for a word that can be hyphenated. This value can tweaked to make text look balanced in some situations. For example, we may want to prevent hyphenation of short words if the text contains many long words that are likely to be hyphenated.

Secondly, we can define exceptions for words that are incorrectly hyphenated or prevent hyphenation of some words altogether. This is done by including a comma-separated list of words in the language object where U+2027 code point is used to specify the desired hyphenation:

const h = new Hypher({
  ...english,
  exceptions: 'donothyphenateme, fix\u2027me'
});

However, do not expect that hyphenation will make your typography look amazing. The hyphenation is done only in the worst case where a long word must be broken into multiple lines. Regular text with enough space will still be rendered without hyphenation as before. This seems to be a limitation of React Native (or underlying platform) and its fast but simple line-breaking algorithm.

Alternatives

Automatic hyphenation with a library like Hypher is a quick and flexible solution. However, this requires additional dependencies and adds a runtime cost. In some situations these downsides can be avoided:

How hyphenation works

Most hyphenation libraries seem to be ports of the hyphenation algorithm used in the TeX typesetting system. Because this algorithm is based on character patterns, it may not be perfectly accurate with every language and all words like proper nouns (e.g. names of people). Overall the results are still very good.