Upgrade to Pro — share decks privately, control downloads, hide ads and more …

実行場所を意識させない i18n API を作った話

実行場所を意識させない i18n API を作った話

柿森 隆生
2026 年 8 月 21 日
React Tokyo ミートアップ #19

Avatar for ANDPAD inc

ANDPAD inc

August 21, 2026

More Decks by ANDPAD inc

Other Decks in Programming

Transcript

  1. 自己紹介 | Speaker 柿森 隆生 GitHub | Urotea ポジション: TechLead(プロダクトのためになんでもやる人)

    最近よく書いている言語: skills(言語なのか?) 趣味: LoL / OW © 2026 ANDPAD All Rights Reserved. Confidential 2
  2. 動く場所を先に決めさせられる | next-intl の場合 'use client'; // ← これでサーバーから使えなくなる import

    { useTranslations } from 'next-intl'; export const ReportListItem = (props: Props) => { const t = useTranslations('report'); // ← サーバーでは getTranslations return ( <li> <span>{t('date')}:{props.date}</span> <span>{t('count', { count: props.count })}</span> </li> ); }; クライアントは useTranslations 、サーバーは getTranslations と関数が分かれる 加えて next.config へのプラグイン追加と、Provider がもう一段 © 2026 ANDPAD All Rights Reserved. Confidential 4
  3. 単純に引数で渡す | colocale import { createTranslator, type Messages } from

    'colocale'; import { reportItemTranslations } from './translations'; export const ReportListItem = (props: Props & { messages: Messages }) => { const t = createTranslator(props.messages, reportItemTranslations); return ( <li> <span>{t('date')}:{props.date}</span> <span>{t('count', { count: props.count })}</span> </li> ); }; 場所を知る責任が呼び出し側に移り、コンポーネントはどこでも動く 利用する辞書は translations.ts に置く: defineRequirement('report', ['date', 'count']) © 2026 ANDPAD All Rights Reserved. Confidential 6