線が違う場所にあった
このサイト自身がかつてそうでした。コンテンツ —— サービス、事例、FAQ —— はデータベースにあり、ナビゲーションの文言、heroの見出し、フォームのラベル、エラーメッセージはフロントエンドに直書きされていました。その線は自然に見えます。これはコード、あれはデータ。しかしそれはエンジニアの視点から引かれた線でした。
誰が変更するのかで見る
heroの見出しを書き直したい人は、サービス説明を書き直したい人と同じです。しかも見出しのほうが変更頻度は高い。最も多くの来訪者が読む一文だからです。コードに置くことは、「文言を一行変えるには公開作業が要る」という規則を定めることであり、その規則を執行するのはプロダクト責任者ではなく、エンジニアの予定表です。
代償は、とても平たい表
第二の仕組みは作りません。UIの文言も (locale, key) の一行であり、同じ管理画面で編集し、同じキャッシュを通ります。違いは平たいことと、キーをこちらが決めることだけです。入れ子にはしません —— 入れ子にすると、管理画面が「あの一文はどこにあるか」に検索窓ひとつで答えられなくなります。編集者が本当に必要とする機能はそれだけです。
見つからないキーは、キー自体を表示する
細部ですが、この仕組みが劣化するかどうかを決めます。値のないキーは空文字ではなく、キーの文字列として描画されます。ページ上の空白は設計判断のように見え、数か月生き延びます。nav.pricing という文字列がナビゲーションの中央にあれば、その日の午後に直されます。
予想していなかった利点
三つの言語が、それぞれの都合で分岐できるようになりました。日本語版の一文を短くしたいとき、中国語版と英語版が固まるのを待つ必要がありません。三つの行であって、一行の三つの列ではないからです。翻訳テーブルを前提とした構成ではこれができません。そしてコンテンツは、実際に分岐します。
コードに残すもの
すべての文字列を移すべきではありません。エラーコード、ログ、機械向けの文言はソースに残します。変更する人がもともとエンジニアであり、変更はコードと一緒にレビューされるべきだからです。判断基準は常に同じです —— 誰がこれを編集したいのか、そのとき何が起きることを期待しているのか。