Internationalisation
is a piece of cake
Eli schutze
ui developer
@elibelly
👋
👶🏽 ❤️ 🤓 📝 🏡
🇲🇽🇳🇮🇺🇸🇨🇳🇬🇧
united kingdom
nicaragua
Internationalisation
is a piece of cake*
*not really**
**actually not at all
react-intl
i18n? wtf?
🤔
@elibelly
Numeronym
A number-based word
- K9, l8r
- 411, 007
- i18n, l10n, a11y
- ... n7m, a16z
@elibelly
i18n? wtf?
🤔
@elibelly
the internet ™
@elibelly
Estimated percentages of the top 10 million websites using various content languages as of October 2017
estimates of the number of Internet users by language as of June 2017
https://w3techs.com/technologies/overview/content_language/all
http://www.internetworldstats.com/stats7.htm
@elibelly
Internationalisation
If you internationalise, you design or develop your content, application, specification, and so on, in a way that ensures it will work well for, or can be easily adapted for, users from any culture, region, or language.
W3C Standards
@elibelly
think about..
- Writing System - é, โลก, 世界
- Language
- Formatting: Date, Time, Currency - 01/09/17
- Writing Direction
- Ordering, Pluralisation
- Grammar
- Relative time
- Locale *
*LOCALEs ≠ language
@elibelly
i18n cake
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
library integration
🕯🕯🕯🕯🕯
i18n cake
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
react-intl
🕯🕯🕯🕯🕯
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
React Intl
🕯🕯🕯🕯🕯
unicode
A standard for consistent encoding, representation, and handling of text expressed in most of the world's writing systems.
This includes all world languages and emoji! 🙌
Includes various encodings, most used is UTF-8, the most widely used by websites. 1-4 bytes.
Solves the writing system consideration!
@elibelly
☕️
咖啡
قهوة
coffee
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
React Intl
🕯🕯🕯🕯🕯
BCP47
LOCALEs ≠ language !
Internet Engineering Task Force - best common practice
Tags for Identifying Languages
[Language Tag]-[Subtags]*
- en-US, en-GB
- mn-Cyrl-MN, zh-Hant-HK
- es-419
@elibelly
@elibelly
👶🏽 ❤️ 🤓 📝 🏡
🇲🇽🇳🇮🇺🇸🇨🇳🇬🇧
es_MX es_NI en_US zh_Hans_CN en_UK
es_419
My Locales
what will you show me?
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
React Intl
🕯🕯🕯🕯🕯
CLDR
Unicode - Common Locale Data Repository
Provides key building blocks for software to support the world's languages, with the largest and most extensive standard repository of locale data available.
- XML Repository
- Written in a standard - Locale Data Markup Language (LDML)
- Includes:
- Locale specific formatting paterns
- Translations of names of things
- Language/script details
- Most devs will use CLDR indirectly, via libraries, such as ICU, Closure, or TwitterCLDR
@elibelly
<days>
<dayContext type="format">
<dayWidth type="abbreviated">
<day type="sun">dom.</day>
<day type="mon">lun.</day>
<day type="tue">mar.</day>
<day type="wed">mié.</day>
<day type="thu">jue.</day>
<day type="fri">vie.</day>
<day type="sat">sáb.</day>
</dayWidth>
<dayWidth type="short">
<day type="sun">DO</day>
<day type="mon">LU</day>
<day type="tue">MA</day>
<day type="wed">MI</day>
<day type="thu">JU</day>
<day type="fri">VI</day>
<day type="sat">SA</day>
</dayWidth>
<dayWidth type="wide">
<day type="sun">domingo</day>
<day type="mon">lunes</day>
<day type="tue">martes</day>
<day type="wed">miércoles</day>
<day type="thu">jueves</day>
<day type="fri">viernes</day>
<day type="sat">sábado</day>
</dayWidth>
</dayContext>
</days>
CLDR 'Days' Section for Spanish Language
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
React Intl
🕯🕯🕯🕯🕯
ICU
set of C/C++ and Java libraries providing Unicode and Globalization support for software applications
international components for unicode
defines
Stores variable data between { curly braces }
@elibelly
- Welcome, { name } !
- There were { count, number } people there - 1,000 vs 1.000
- My birthday is { birthday, date, short } - 01/02/2017 vs 02/01/2017
- { gender, select,
male { He likes trains },
female { She likes trains },
other { They like trains }
} - { count , plural ,
=0 {No more seats available }
one {Just a single seat left!}
other {# seats left}} - *some languages have few and many !
@elibelly
🚨 Javascript Alert 🚨
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
React Intl
🕯🕯🕯🕯🕯
ECMAScript INTL API
@elibelly
ECMA 402
-
Intl.NumberFormat
-
Intl.DateTimeFormat
-
Intl.Collator
- Constructor takes locale and formatting options
- Exposes main method (compare() or format())
- Currently being worked on TC39
@elibelly
var myNumber = 123456.789;
// the Japanese yen doesn't use a minor unit
console.log(
new Intl.NumberFormat('ja-JP',
{ style: 'currency',
currency: 'JPY' })
.format(myNumber)
)
// → ¥123,457
// request a weekday along with a long date
var options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric' };
console.log(
new Intl.DateTimeFormat('de-DE', options).format(date)
);
// → "Donnerstag, 20. Dezember 2012"
@elibelly
- Not supported in older browsers
- Expensive (esp. in React)
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
React Intl
🕯🕯🕯🕯🕯
FORMAT JS
- Open sourced by Yahoo
- Modular collection of I18n javascript libraries
- Has core libs built on standards
- Provides integration modules
- Robust - works down to ES3 & IE 6 as well as Node
@elibelly
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
React Intl
🕯🕯🕯🕯🕯
FORMAT JS - CORE
- Exports Javascript API with more functionality than ECMA
- Polyfills where needed
@elibelly
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
React Intl
🕯🕯🕯🕯🕯
REACT INTL
-
Config
-
addLocaleData
-
intlShape
-
injectIntl
-
defineMessages
-
-
Wrapper: IntlProvider
- Components:
-
FormattedDate
-
FormattedTime
-
FormattedRelative
-
FormattedNumber
-
FormattedPlural
-
FormattedMessage
-
https://github.com/yahoo/react-intl
@elibelly
Setup
- Load Locale Data
- Add i18n context to React App
- Provide app specific messages (strings)
- Use Components!
@elibelly
Load Locale Data
import { IntlProvider, addLocaleData } from 'react-intl';
import en from 'react-intl/locale-data/en';
import ru from 'react-intl/locale-data/ru';
import es from 'react-intl/locale-data/es';
import fr from 'react-intl/locale-data/fr';
addLocaleData([...en, ...fr, ...es, ...ru]);
If on the client side, each extra locale (usually language) is loaded in as a separate bundle
On the node all locales are loaded into memory server-side
@elibelly
ADD CONTEXT
import { IntlProvider, addLocaleData } from 'react-intl';
...
// This should be the only place where you update the locale
const locale = 'es-419';
const messages = require(`./locales/${locale}.json`);
ReactDOM.render(
<IntlProvider locale={locale} messages={messages}>
<App />
</IntlProvider>,
document.getElementById('root')
);
@elibelly
Provide messages
// es-419.json
{
"nameInput.placeholder": "Por favor introduzca su nombre...",
"app.header": "Ejemplos de React Intl",
"app.welcome_message":
"{gender, select,
female {Bienvenida}
male {Bienvenido}
other {Bienvenidx}} {name}, {unreadCount, plural,
=0 {no tienes messages}
one {tienes {formattedUnreadCount} mensaje nuevo}
other {tienes {formattedUnreadCount} mensajes nuevos}} desde {formattedLastLoginTime}.",
"app.currentTime": "Hora actual: ",
"app.you": "tú"
}
@elibelly
USE COMPONENTS - (examples)
<FormattedNumber value={unreadCount} /> // 1,234 vs 1.234
<FormattedMessage id="app.login_screen.header" defaultMessage="This is a Header" />
<FormattedTime value={Date.now()} timeZoneName="long" />
<FormattedMessage
id="app.welcome_message"
defaultMessage={`
Welcome {name}, you have received {unreadCount, plural,
=0 {no new messages}
one {{formattedUnreadCount} new message}
other {{formattedUnreadCount} new messages}
} since {formattedLastLoginTime}.
`}
values={{
name: (
<b>
{this.state.name || (
<FormattedMessage id="app.you" defaultMessage="you" />
)}
</b>
),
unreadCount: unreadCount,
formattedUnreadCount,
formattedLastLoginTime,
gender,
}}
/>
🎉
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
react-intl
🕯🕯🕯
what about the candles
other challenges
🕯 Locale Detection
🕯 Performance
🕯 Continuous Localisation
import {
IntlProvider,
addLocaleData
} from 'react-intl';
...
// This should be the only place
// where you update the locale
const locale = 'es-419';
Locale detection
-
accept headers vs
geo/IP ? - UI - good practice to let the user choose!
- browser? cookies? app storage?
- UX & Auth - are they a
recognised user? a guest? - meaningful fallbacks
Content negotiation
Performance
- locales and bundle size
- polyfills
- caching
Continuous Localisation
- ease
- price
- services & features
It is a way of automatically, seamlessly gathering new source material, publishing it for translation, acquiring translations and integrating them back into the product.
i18l has a logistics problem
internationalisation
is part of accessibility
💡
Unicode
BCP47
CLDR
ICU
ECMAScript Intl API
Format JS Core
react-intl
🕯🕯🕯
Thank you
👋
@elibelly
Internationalisation is a Piece of Cake
By Eli Schütze Ramírez
Internationalisation is a Piece of Cake
While about 51% of the world’s websites are in English, only about 25% of web users are English speakers. With half of the world’s population online, internationalisation is as relevant as ever! Let’s explore how i18n gets made on the web.
- 2,409