RORK LABEN
MAX — Rork MaxはReact NativeではなくネイティブSwiftアプリを生成し、Appleエコシステム全体を対象にしますDEVICES — iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageまで、一つの記述から広げられますNATIVE — AR・LiDARスキャン、Metalによる3Dゲーム、ウィジェット、Dynamic Island、オンデバイスCore MLを解放しますSEED — RorkはLeft Lane Capital主導の$15Mシードを調達し、Peak XVやa16z Speedrunも参加しましたPAPERLINE — アプリビルダーPaperlineを買収し、エンジニアリング人材の獲得を続ける姿勢ですMARKET — 月間743,000訪問超。Gartnerは2026年末までに新規アプリの75%がローコード/ノーコードで作られると見込みますMAX — Rork MaxはReact NativeではなくネイティブSwiftアプリを生成し、Appleエコシステム全体を対象にしますDEVICES — iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageまで、一つの記述から広げられますNATIVE — AR・LiDARスキャン、Metalによる3Dゲーム、ウィジェット、Dynamic Island、オンデバイスCore MLを解放しますSEED — RorkはLeft Lane Capital主導の$15Mシードを調達し、Peak XVやa16z Speedrunも参加しましたPAPERLINE — アプリビルダーPaperlineを買収し、エンジニアリング人材の獲得を続ける姿勢ですMARKET — 月間743,000訪問超。Gartnerは2026年末までに新規アプリの75%がローコード/ノーコードで作られると見込みます
記事一覧/開発ツール
開発ツール/2026-07-15上級

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

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

Rork510React Native209Expo143日本語タイポグラフィ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/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

開発ツール2026-07-10
React Compiler を Expo に入れて、手書き memo を 41 箇所消しました
Rork が生成した React Native 画面に React Compiler を導入し、再レンダリング回数を Profiler で実測しました。手書き memo/useCallback の削除判断、効かない箇所の見分け方、CI での回帰検知までをまとめています。
開発ツール2026-07-07
アイコンのバッジが「3」のまま消えない — Expoアプリのバッジ数をSource of Truthで作り直す
Expoアプリのアイコンバッジが実際の未読と食い違い、消えなくなる原因を突き止め、バッジ数を状態から再計算して同期するSource of Truth設計を、動くコードと実運用の落とし穴つきで整理します。
開発ツール2026-07-04
「続きを読む」を出すべきか、テキストの実測で決める — Rork(Expo)の折りたたみ表示設計
商品説明やレビュー本文を3行で畳み「続きを読む」を出す実装で、短い文にまでトグルが付いてしまう問題を解決します。onTextLayout で実際の行数を測り、はみ出す時だけトグルを出す設計を、iOS と Android の差、展開アニメーション、文字サイズ拡大への配慮まで動くコードでまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →