RORK LABEN
PLAY — Google Play の target API level 36 要件が昨日8月31日に発効しました。今日以降、新規アプリと既存アプリの更新は Android 16 対応が必須ですVISIBILITY — API 35 のままのアプリは掲載こそ続きますが、新しい Android 版のユーザーには表示されなくなります。エラーが出ないまま新規インストールだけが減る点に注意が要りますEXTENSION — 間に合わなかった場合は、Play Console から2026年11月1日までの延長申請が出せます。恒久対応の計画とセットで進めるのが実務的ですAPPLE — Apple 側は9月9日にイベント、iOS 27 の正式リリースは9月14日と報じられています。生成したアプリの iOS 27 実機確認はリリース週の前に済ませておきたいところですEXPO — Expo が expo-paste-input を公開しました(8月28日)。React Native の TextInput に画像・GIF・ステッカーの貼り付けを追加するネイティブモジュールですEAS — EAS Observe が8月20日に GA になりました。クラッシュや性能の観測を、ビルドや配信と同じ EAS 上で持てるようになっていますPLAY — Google Play の target API level 36 要件が昨日8月31日に発効しました。今日以降、新規アプリと既存アプリの更新は Android 16 対応が必須ですVISIBILITY — API 35 のままのアプリは掲載こそ続きますが、新しい Android 版のユーザーには表示されなくなります。エラーが出ないまま新規インストールだけが減る点に注意が要りますEXTENSION — 間に合わなかった場合は、Play Console から2026年11月1日までの延長申請が出せます。恒久対応の計画とセットで進めるのが実務的ですAPPLE — Apple 側は9月9日にイベント、iOS 27 の正式リリースは9月14日と報じられています。生成したアプリの iOS 27 実機確認はリリース週の前に済ませておきたいところですEXPO — Expo が expo-paste-input を公開しました(8月28日)。React Native の TextInput に画像・GIF・ステッカーの貼り付けを追加するネイティブモジュールですEAS — EAS Observe が8月20日に GA になりました。クラッシュや性能の観測を、ビルドや配信と同じ EAS 上で持てるようになっています
記事一覧/開発ツール
開発ツール/2026-07-15上級

「、」が行頭に落ちた — Rork が組んだ名言カードと日本語の禁則処理

React Native の Text は日本語の行頭禁則を保証しません。実測した違反率、WORD JOINER による事前結合の実装、onTextLayout での自動監査、Rork Max(SwiftUI)との挙動差までまとめました。

Rork547React Native233Expo192日本語タイポグラフィText

プレミアム記事

iPhone SE の実機を手に取って、画面の中央で止まりました。

壁紙アプリの名言カード。二行目が「、深い呼吸をひとつ。」から始まっています。読点が行頭に落ちていました。

Rork に「引用文をカード中央に大きく表示して」と頼んで生成された画面です。コードは正しく動いています。レイアウトも崩れていません。ただ、日本語として組まれていない。

シミュレータの iPhone 15 Pro では起きませんでした。幅が違うと折り返し位置が変わるので、たまたま見えていなかっただけです。

React Native の Text は禁則を保証していない

React Native の Text は、行分割を自分では実装していません。iOS では TextKit / CoreText に、Android では android.text.LineBreaker に、それぞれ委譲しています。

つまり折り返しの品質は、プラットフォームとロケール設定に依存します。ここが厄介でした。

環境行頭禁則の扱い私が観測した挙動
iOS(既定)CoreText がある程度考慮「、」「。」は概ね回避。ただし長音符「ー」や小書き仮名「っ」は行頭に落ちる
iOS(lineBreakStrategyIOS="push-out"押し出し方式で回避違反は大きく減るが、行数が増える場合がある
Android(既定 simpleほぼ考慮しない読点・句点・閉じ括弧が行頭に落ちる
Android(textBreakStrategy="balanced"行長を均す方針見た目は整うが禁則そのものは保証されない

「Android では日本語ロケールなら禁則が効くはず」と考えていました。実際には、端末の言語設定ではなく、テキストに紐づくロケール情報で判定されます。アプリ内で日本語を表示していても、端末が英語設定なら期待した処理は走りません。

私のアプリは16言語に対応しています。ユーザーの端末言語は日本語とは限らない。この前提を見落としていました。

まず違反率を測りました

感覚で直すと、直った気になるだけで終わります。数字を取りました。

計測対象は、癒し系・引き寄せ系を含む壁紙アプリ6本で使っている名言テキスト120本。デバイス幅は 320 / 375 / 393 / 430 の4種です。

onTextLayout は、レイアウト確定後の各行を返してくれます。行の先頭文字を見れば、違反はそのまま判定できます。

// KinsokuAudit.tsx — 実行時に行頭禁則違反を検出する
import { Text, type TextLayoutEventData, type NativeSyntheticEvent } from "react-native";
 
// 行頭に来てはいけない文字(約物・小書き仮名・長音符・繰り返し記号)
const LINE_START_FORBIDDEN =
  "、。,.・:;?!ヽヾゝゞ々ー’”)〕]}〉》」』】…‥" +
  "ぁぃぅぇぉっゃゅょゎァィゥェォッャュョヮヵヶ";
 
type Violation = { lineIndex: number; head: string; lineText: string };
 
export function auditLines(
  e: NativeSyntheticEvent<TextLayoutEventData>
): Violation[] {
  const lines = e.nativeEvent.lines;
  const out: Violation[] = [];
 
  // 1行目は「行頭」ではあっても折り返し起因ではないので除外する
  for (let i = 1; i < lines.length; i++) {
    const text = lines[i].text ?? "";
    const head = Array.from(text)[0];
    if (!head) continue;
    if (LINE_START_FORBIDDEN.includes(head)) {
      out.push({ lineIndex: i, head, lineText: text });
    }
  }
  return out;
}
 
export function QuoteCard({ quote, onAudit }: { quote: string; onAudit?: (v: Violation[]) => void }) {
  return (
    <Text
      style={{ fontSize: 22, lineHeight: 36 }}
      onTextLayout={(e) => onAudit?.(auditLines(e))}
    >
      {quote}
    </Text>
  );
}

1行目を除外している理由は、折り返しで生じた行頭だけを数えたいからです。原文が読点で始まることは通常ありませんが、除外しておくほうが数字の意味が明確になります。

これを4つの固定幅コンテナに並べて、120本を流しました。結果です。

条件違反行数 / 総折り返し行 (iOS)違反行数 / 総折り返し行 (Android)
素の Text(既定)31 / 664(4.7%)96 / 671(14.3%)
lineBreakStrategyIOS="push-out" のみ9 / 682(1.3%)96 / 671(14.3%)
textBreakStrategy="balanced" のみ31 / 664(4.7%)88 / 669(13.2%)
事前結合(後述)0 / 689(0%)0 / 690(0%)

Android の14.3%が効きました。7行に1行の割合で、日本語として不自然な折り返しが出ていたことになります。

iOS の push-out は効果が大きい一方で、残った9件は長音符と小書き仮名でした。プラットフォームの判断に委ねると、そこまでは面倒を見てくれません。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
名言120本×4デバイス幅で行頭禁則違反を実測した数字と、その計測手順
WORD JOINER を使った事前結合の実装(コピペ・読み上げを壊さない書き方)
onTextLayout でCIから違反を検出する監査ハーネスと、Rork Max(SwiftUI)との挙動差
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

関連記事

開発ツール2026-08-22
一括置換は全ファイル成功しました。壊れたのは、消さなかった行のほうです
生成コードに一括置換をかけると、一致した行ではなく隣の行が壊れます。運用中のプロジェクトで実際に起きた破損と、置換の不変条件を検査する20行のガードスクリプトをまとめました。
開発ツール2026-07-30
Renovate が触ってよい依存と、触ってはいけない依存 — Expo SDK 57 の123パッケージを機械的に切り分ける
Rork 生成アプリに依存の自動更新を入れると、Expo が版を管理している123パッケージまで巻き込まれます。2026年7月30日時点の実測では、うち6件が npm の最新版へメジャー更新される差でした。除外リストを手で書かず SDK から機械生成する手順をまとめます。
開発ツール2026-07-28
prebuild --clean で消える手入れを、上げる前に数える — Expo SDK 57 移行の棚卸し
Expo SDK 57 への移行前に、ios/ へ加えた手入れが prebuild の再生成でいくつ失われるかを数える手順をまとめました。素の差分649行のうち意味を持つのは3行。ノイズを正規化して実質的な変更だけを抽出するスクリプトと、config plugin への移し替えを実測つきで共有します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →