Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
実行場所を意識させない i18n API を作った話
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
ANDPAD inc
August 21, 2026
Programming
250
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
実行場所を意識させない i18n API を作った話
柿森 隆生
2026 年 8 月 21 日
React Tokyo ミートアップ #19
ANDPAD inc
August 21, 2026
More Decks by ANDPAD inc
See All by ANDPAD inc
R8 の設定見直しでアプリサイズ削減
andpad
0
220
Go 探無比ワークショップ開催レポート
andpad
0
93
self-service-infrastructure-with-argocd-and-atlantis
andpad
0
16
Go 1.27 における memory allocation の高速化
andpad
0
460
言語を使う側から、作る側へ。 自作 Lisp で得た新たな気づき。
andpad
0
230
OS アップデート対応の取り組み方がもっと共有されてほしい
andpad
0
160
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
630
ANDPAD Ruby sponsor session in RubyKaigi 2026
andpad
0
310
AWS WAFの運用を地道に改善し、自社で運用可能にするプラクティス
andpad
2
1.4k
Other Decks in Programming
See All in Programming
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
190
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
180
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
300
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
190
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
270
Seven New Principles of Software Engineering
yegor256
0
130
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2.3k
contenteditable と日本語入力に向き合う
colorful12
0
200
Compiling a real-world CLI tool to native with Static Hermes
tmikov2023
0
130
npm との違いを手がかりにGo の依存管理を理解したい
optim
0
990
ソニーのクラウド共通基盤の変遷とAI時代の開発スタイルに合わせた進化 / The Journey of Sony’s Common Cloud Platform and Its Evolution for AI-Native Development
kenjiyoneyama
0
290
Featured
See All Featured
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
330
ラッコキーワード サービス紹介資料
rakko
2
5.4M
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3.1k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
370
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
1
280
Designing for Timeless Needs
cassininazir
1
530
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
480
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
540
Being A Developer After 40
akosma
92
590k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.2k
Typedesign – Prime Four
hannesfritz
42
3.2k
Transcript
実行場所を意識させないi18n APIを作った話 colocaleというOSSを作りました © 2026 ANDPAD All Rights Reserved. Confidential
自己紹介 | Speaker 柿森 隆生 GitHub | Urotea ポジション: TechLead(プロダクトのためになんでもやる人)
最近よく書いている言語: skills(言語なのか?) 趣味: LoL / OW © 2026 ANDPAD All Rights Reserved. Confidential 2
ただ表示する言葉を変えるだけのはずだった どの言語を表示するかの分岐はスコープ外とさせてください。 今回の話は言語ごとにラベルを入れ替えるだけの小さな部品の話です。 ラベルを日本語と英語で切り替えたい 該当のコンポーネントはサーバーコンポーネントからもクライアントからも使いたい next-intlのようなi18nライブラリは、サーバーとクライアントでAPIが分かれているので、コンポーネントが 動く場所を意識せざるを得ない さらにプラグインの追加やProviderの追加も必要になる ラベルを差し替えるだけなのに、なぜか設計の話になった。 ©
2026 ANDPAD All Rights Reserved. Confidential 3
動く場所を先に決めさせられる | 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
動く場所を意識させるAPIは再利用性を殺す 先の例のような小さな部品ほど、サーバーとクライアントの両方で使いたい なのにi18nのAPIが場所ごとに分かれていると、部品が動く場所に縛られる サーバーとクライアントで実行モデルが違うのは当然。問題はその違いをコンポーネント自身に意識させてい ること プラグインやProviderの追加も不要で、実行場所を意識せず、ラベルを差し替えるだけのAPIが欲しい © 2026 ANDPAD All
Rights Reserved. Confidential 5
単純に引数で渡す | 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
代償とまだ解けていないこと Propsに messages が増える。いわゆるバケツリレー requirementを取り違えて絞ると、型は通るのに実行時にキーが足りない Messages 型がrequirementでパラメータ化されていないため 回避策はある: requirementを大きめの粒度で作ったり、requirementを省略して指定言語の全辞書を渡す(小 規模ならこれで十分)
宿題: 足りないキーをコンパイルエラーにする方法を探しています。心当たりのある方は教えてください。 © 2026 ANDPAD All Rights Reserved. Confidential 7
まとめ RSC時代に欲しかったのは、動く場所を知らなくていいi18n API Providerを捨てて引数で渡すだけで、同じコンポーネントがサーバーでもクライアントでも動く 副産物として、React以外でも同じ書き方が使える(Vueにも対応) colocale github.com/Urotea/colocale おまけ: 翻訳をYAMLで書いてJSONに変換するyamlocaleも公開しています(i18next /
react-intl / vue-i18n でも使えます) github.com/Urotea/yamlocale © 2026 ANDPAD All Rights Reserved. Confidential 8