◉RORK LABEN
●GPT6.1 — Rork のモデルメニューに GPT-6.1 Sol が加わりました(9月29日)。GPT-6 Sol と同価格で、1M トークンの文脈を読みます●SDK58 — Expo SDK 58 Beta が公開されました(React Native 0.88 RC 同梱)。安定版の日付はまだ確認できていません●10/12 — React Native 0.88.x の正式リリース予定まで残り5日。Expo Go の更新で SDK 57 のサポートが落ちる流れです●TESTFLIGHT — Mac なし・Windows だけで iPhone アプリを TestFlight に載せた手順と、つまずいた4か所が Zenn に出ています●NEW — Sonnet 5.5・GPT-6.1 Sol・Opus 5.5 のどれに頼むかを修正の種類で決め、クレジットの行き先を1週間記録しました●EXPO — Shopify がネイティブに戻る中で、1人開発では Expo に残る、という判断の記事が Zenn に出ています。確かめる人が1人という点が論点です●GPT6.1 — Rork のモデルメニューに GPT-6.1 Sol が加わりました(9月29日)。GPT-6 Sol と同価格で、1M トークンの文脈を読みます●SDK58 — Expo SDK 58 Beta が公開されました(React Native 0.88 RC 同梱)。安定版の日付はまだ確認できていません●10/12 — React Native 0.88.x の正式リリース予定まで残り5日。Expo Go の更新で SDK 57 のサポートが落ちる流れです●TESTFLIGHT — Mac なし・Windows だけで iPhone アプリを TestFlight に載せた手順と、つまずいた4か所が Zenn に出ています●NEW — Sonnet 5.5・GPT-6.1 Sol・Opus 5.5 のどれに頼むかを修正の種類で決め、クレジットの行き先を1週間記録しました●EXPO — Shopify がネイティブに戻る中で、1人開発では Expo に残る、という判断の記事が Zenn に出ています。確かめる人が1人という点が論点です
記事一覧/開発ツール
⬡ 開発ツール/2026-10-07中級

日本語の見出しだけ太字にならない — Android で fontWeight が効かないときの切り分けと直し方

Rork で作ったアプリで、iPhone では太字なのに Android では日本語の見出しが細いままになる症状の切り分け記事です。原因の見分け方、fontFamily を重みごとに分ける直し方、確認用コードを載せています。

Rork576Expo213expo-fontfontWeightNoto Sans JPAndroid53トラブルシューティング80

生成された画面を iPhone で確認して、「よし」と閉じてしまうことがあります。Android での見え方は、あとで見ればいい——私がよくやってしまう順番です。

その「あとで」に Android の実機を開くと、見出しが妙に細く見えるのです。コードを見ると fontWeight: "700" はちゃんと書いてあります。iPhone では太く出ていたのに、です。英数字の部分は太いのに、日本語の部分だけ細いままという見え方になることもあります。

この記事は、その症状に出会った方が 見分け → 切り分け → 直す → 確かめる の順で進められるように書き残します。

まず、症状を3つに分けます

「太字にならない」と言っても、見え方は少しずつ違います。どれに当てはまるかで、疑う場所が変わります。

見え方疑う場所
iPhone は太い。Android だけ全部細いfontFamily と fontWeight の組み合わせ
英数字は太いのに、日本語だけ細い日本語を含むフォントを読み込んでいない(フォールバック)
太字にしたら、ひと目で「ずれた」と分かる別の見た目になる重みごとの別フォント名を取り違えている

一つ目が最も多く、この記事の中心もそこです。二つ目と三つ目は、次の切り分けの途中で自然に拾えます。

原因の切り分けは、この順番です

手順は短く、上から順に一つずつ確認します。

1. 太字にしている Text が、どの fontFamily を使っているか確認します。

生成されたコードの中で、fontWeight を書いている箇所を探します。

grep -rn "fontWeight" app components | head -30

見つかった行の近くに fontFamily があるかどうかを見ます。fontFamily: "NotoSansJP_400Regular" のように Regular 用の名前を指したまま fontWeight: "700" だけを足している形が、症状の典型です。

2. 読み込んでいるのが、Regular だけではないか確認します。

useFonts に渡している一覧を見ます。ここに Bold が無ければ、Android には太字として使える実体がそもそもありません。

3. 名前の綴りを確認します。

useFonts のキーと、fontFamily に書いた文字列は完全に一致している必要があります。拡張子や - と _ の違いで外れたとき、エラーにならずシステムフォントで表示されることが多く、気づきにくいのです。フォント読み込みの基本はRork アプリでカスタムフォントを美しく読み込むにまとめてあります。

ここまでで、ほとんどの場合は原因が見つかります。

考え方は「重みごとに、別の名前を持たせる」です

私が最終的に落ち着いた考え方を、短くお伝えします。仕組みとしては、こうです。

iPhone は、フォントファミリーと太さの指定から、近い太さの実体を探してくれる場面が多いのに対し、Android はファミリー名で実体を直接引く性格が強く、Regular の実体に fontWeight を足しても、Bold の実体には切り替わってくれないことがある、ということです。両方の OS で同じ見た目にしたいなら、重みごとに別の名前でフォントを読み込み、fontWeight ではなく fontFamily で太さを選ぶ形に寄せるのが安全です。

この考え方に沿えば、OS の違いに頼らずに済みます。

直し方:重みを名前に持たせる

Noto Sans JP を Google Fonts のパッケージから読み込む例です。

npx expo install expo-font @expo-google-fonts/noto-sans-jp

何を解決するコードか——Regular・Medium・Bold を別名で読み込み、画面側は weight という意味のある名前だけを渡せるようにします。

// components/AppText.tsx
import { Text as RNText, TextProps } from "react-native";
 
type Weight = "regular" | "medium" | "bold";
 
const FAMILY: Record<Weight, string> = {
  regular: "NotoSansJP_400Regular",
  medium: "NotoSansJP_500Medium",
  bold: "NotoSansJP_700Bold",
};
 
type Props = TextProps & { weight?: Weight };
 
export function AppText({ weight = "regular", style, ...rest }: Props) {
  return (
    <RNText
      {...rest}
      style={[
        { fontFamily: FAMILY[weight] },
        style,
        // 太さは fontFamily で決める。ここで標準に戻し、二重指定を防ぐ
        { fontWeight: "normal" },
      ]}
    />
  );
}
// app/_layout.tsx(読み込み側)
import { useFonts } from "expo-font";
import {
  NotoSansJP_400Regular,
  NotoSansJP_500Medium,
  NotoSansJP_700Bold,
} from "@expo-google-fonts/noto-sans-jp";
import * as SplashScreen from "expo-splash-screen";
import { useEffect } from "react";
import { Stack } from "expo-router";
 
SplashScreen.preventAutoHideAsync();
 
export default function RootLayout() {
  const [loaded, error] = useFonts({
    NotoSansJP_400Regular,
    NotoSansJP_500Medium,
    NotoSansJP_700Bold,
  });
 
  useEffect(() => {
    if (loaded || error) SplashScreen.hideAsync();
  }, [loaded, error]);
 
  if (!loaded && !error) return null;
  return <Stack />;
}

なぜこう書くか。 AppText の末尾で fontWeight を標準に戻しているのは、あとから誰か(あるいは AI)が fontWeight: "700" を足しても、Regular の実体に太さだけを重ねる形に戻らないようにするためです。太さの入口を weight の一本にしておくと、生成コードを読み返すときも、疑う場所が一つで済みます。

直ったかどうかは、3行の確認画面で見ます

本番の画面を直す前に、確認用の画面で3つの重みを並べます。日本語・英数字・記号を混ぜておくと、二つ目の症状(日本語だけ細い)も一緒に見分けられます。

// app/font-check.tsx
import { View } from "react-native";
import { AppText } from "../components/AppText";
 
export default function FontCheck() {
  return (
    <View style={{ padding: 24, gap: 12 }}>
      <AppText weight="regular" style={{ fontSize: 20 }}>標準 Regular 日本語ABC123</AppText>
      <AppText weight="medium" style={{ fontSize: 20 }}>中太 Medium 日本語ABC123</AppText>
      <AppText weight="bold" style={{ fontSize: 20 }}>太字 Bold 日本語ABC123</AppText>
    </View>
  );
}

見るのは一点だけです。iPhone と Android の両方で、3行の太さが段階的に違って見えるか。 並べ方が崩れず、日本語の文字も英数字と同じ段階で太くなっていれば、直っています。

直し終えたあとに残りやすい落とし穴

  • ファイルサイズ。 日本語フォントは、重みを増やすたびにアプリに同梱されるサイズが増えます。Regular と Bold の2本で足りるなら、Medium は後から足す判断で十分です。
  • AI に頼むときの書き方。 Rork に修正を依頼するときは、「fontWeight を使わず、重みごとに別の fontFamily を指定してください。使うのは Regular と Bold の2つです」と、ここまで書いておくと意図が伝わりやすくなります。
  • 直らなかったとき。 useFonts の戻り値の error を一度ログに出して、読み込み自体が失敗していないかを確認してください。名前の不一致は、画面では静かに別のフォントになるだけなので、ログのほうが早く教えてくれます。

次の一歩

壁紙アプリのように日本語の見出しが画面の顔になるアプリほど、この差は目に入りやすいと感じています。まずは、お手元のプロジェクトで grep -rn "fontWeight" app components を一度だけ実行して、ヒットした行の数を数えてみてください。その数が、直す範囲の見積もりになります。

太さは OS の推測に預けず、名前で決めるのです。 個人開発で両方のストアに出している私にとって、この線引きは、これからも守っていきたい一本です。

シェア

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

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

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

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⬡ 開発ツール2026-09-21
exit code 0 で止まるビルド — ログを黙らせていた設定と、空ファイルを通した存在チェック
eas build --local が exit code 0 but produced no further output で止まる件と、0 バイトのスタブが埋め込まれず dyld で落ちる件。どちらも原因は出力を減らす設定でした。自分のスクリプトを棚卸しする手順まで書き残します。
⬡ 開発ツール2026-08-21
生成ループが緑を返した後に、私が手元で回している4つの受け入れ検査
ビルドが成功しても出荷できない状態は実在します。AI がビルドを反復する構成で見落とされやすい4点を、成果物そのものを走査する検査スクリプトとして手元に置く方法をまとめました。
⬡ 開発ツール2026-09-22
R8 が既定になる前に測っておく4つの数字 — Expo SDK 58 を待つあいだの Android 計測メモ
Expo SDK 58 では Android のリリースビルドで R8 が既定で有効になります。有効化の前後を同じ物差しで比べられるよう、AAB のダウンロードサイズ・DEX 合計・コールドスタート・ビルド時間の4つを測って残す手順をまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます