生成された画面を 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 の推測に預けず、名前で決めるのです。 個人開発で両方のストアに出している私にとって、この線引きは、これからも守っていきたい一本です。