RORK LABEN
MAX — Rork MaxはネイティブSwiftアプリを生成し、iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageに対応しますNATIVE — Rork MaxはAR/LiDAR・Metalの3D・ウィジェット・Dynamic Island・Live Activities・HealthKit・Core MLなどネイティブ機能を解放しますSTACK — RorkはReact Native(Expo)でiOS/Androidのネイティブアプリを生成し、英語の説明だけで動くコードを書き出しますGROWTH — Rorkの月間アクセスは743,000件を超え、成長率は85%に達していますPRICE — 料金は無料から始められ、有料プランは月$25から利用できますTREND — Gartnerは2026年末までに新規アプリの75%がローコード/ノーコードで作られると予測していますMAX — Rork MaxはネイティブSwiftアプリを生成し、iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageに対応しますNATIVE — Rork MaxはAR/LiDAR・Metalの3D・ウィジェット・Dynamic Island・Live Activities・HealthKit・Core MLなどネイティブ機能を解放しますSTACK — RorkはReact Native(Expo)でiOS/Androidのネイティブアプリを生成し、英語の説明だけで動くコードを書き出しますGROWTH — Rorkの月間アクセスは743,000件を超え、成長率は85%に達していますPRICE — 料金は無料から始められ、有料プランは月$25から利用できますTREND — Gartnerは2026年末までに新規アプリの75%がローコード/ノーコードで作られると予測しています
記事一覧/開発ツール
開発ツール/2026-07-08中級

SVGアイコンがExpo Goでは出るのにビルドで消える — Rork製アプリでSVGを確実に表示する

Rork や Expo のアプリで .svg ファイルを import してもアイコンが表示されない、色が反映されないという問題を、metro.config.js と react-native-svg-transformer の設定、currentColor によるテーマ追従まで実際のコードで解決します。

トラブルシューティング76SVGExpo135React Native199アイコン2

個人開発で運用している壁紙アプリのタブアイコンを、線の細いオリジナルのSVGに差し替えたときのことです。Expo Go で開くと綺麗に表示されていたので安心して開発ビルドを作ったところ、同じ画面でアイコンだけがぽっかりと消えていました。エラーは出ません。ただ、そこにあるはずの図形が透明になっている。原因にたどり着くまで小一時間かかりましたので、同じところで立ち止まる方のために整理して共有します。

症状

SVGアイコンが絡むと、次のいずれかの形でつまずきます。

  • Expo Go では表示されるのに、開発ビルドや本番ビルドでは何も描かれない
  • Unable to resolve module ./icon.svg という赤い画面が出る
  • 表示はされるが、ダークモードにしても色が黒いまま変わらない
  • iOS では出るのに Android だけ表示されない(またはその逆)

厄介なのは、多くの場合エラーが出ずに「透明な図形」として静かに失敗する点です。レイアウト上の場所は確保されているのに中身が見えないため、CSSの問題だと勘違いして遠回りしがちでした。

再現条件

Rork が生成したコード、あるいは自分で追加したコードで、SVGファイルをこう読み込んでいるケースです。

import TabIcon from "../assets/icons/home.svg";
 
export function HomeTab() {
  return <TabIcon width={24} height={24} />;
}

一見なんの問題もありません。しかし React Native / Expo の Metro バンドラーは、初期状態では .svg を「画像アセット」として扱います。つまり <TabIcon /> はコンポーネントではなく画像ソースのオブジェクトになり、コンポーネントとして描画しようとしても中身が生まれません。

Expo Go でたまたま表示されるのは、キャッシュや古いバンドル、あるいは別経路で読み込まれていたなど環境依存の偶然であることが多く、これに頼ると本番で崩れます。

なぜ表示されないのか

原因は大きく2つに分かれます。

ひとつ目は、.svg をコンポーネントとして import する仕組みが入っていないこと。React Native には Web の <img src="...svg"> のような仕組みがなく、SVGを描くには react-native-svg が必要です。さらに .svg ファイルをそのまま JSX コンポーネントとして扱うには react-native-svg-transformer を Metro に組み込む必要があります。これが無いと Metro は SVG を静的アセット扱いにしてしまいます。

ふたつ目は、色がSVGファイル内に固定で焼き込まれていること。デザインツールが書き出す SVG は fill="#111111" のように具体的な色を持っていることが多く、これだとアプリ側でテーマに応じて色を変えられません。ダークモードで黒いまま消えたように見えるのはこのパターンです。

解決策1: react-native-svg-transformer で .svg を import できるようにする

まず必要なパッケージを入れます。Expo 管理下では npx expo install を使うと SDK に合ったバージョンが入ります。

npx expo install react-native-svg
npm install --save-dev react-native-svg-transformer

次にプロジェクト直下の metro.config.js を編集します。Expo の場合は getDefaultConfig を土台にするのが安全です。ファイルが無ければ新規作成します。

// metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
 
const config = getDefaultConfig(__dirname);
 
// SVG を JSX コンポーネントとして扱えるようにする
config.transformer.babelTransformerPath = require.resolve(
  "react-native-svg-transformer"
);
 
// .svg を「アセット」から外し、「ソースコード」として解決させる
config.resolver.assetExts = config.resolver.assetExts.filter(
  (ext) => ext !== "svg"
);
config.resolver.sourceExts = [...config.resolver.sourceExts, "svg"];
 
module.exports = config;

ポイントは assetExts から svg を除外し、sourceExts に加えるところです。この2行を忘れると transformer を入れても Metro は依然として SVG を画像として扱い続けます。

TypeScript を使っている場合は、.svg を import する型が無いと赤線が出ますので、declarations.d.ts のような型定義ファイルを1枚用意します。

// declarations.d.ts
declare module "*.svg" {
  import type { SvgProps } from "react-native-svg";
  const content: React.FC<SvgProps>;
  export default content;
}

最後に、設定を変えたら Metro のキャッシュを消してから再起動します。ここを飛ばすと古い解決結果が残り、直っているのに直っていないように見えます。

npx expo start --clear

これで先ほどの import TabIcon from "../assets/icons/home.svg" が、そのままコンポーネントとして描画されるようになります。

解決策2: currentColor でテーマに追従させる

表示はできても色が変わらない問題は、SVGの fill を固定色から currentColor に置き換えることで解決します。react-native-svg-transformer は SVG 内の currentColor を、コンポーネントに渡した color プロップに橋渡ししてくれます。

書き出された SVG のパスがこうなっていたら、

<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  <path fill="#111111" d="M12 3l9 7v11h-6v-6H9v6H3V10z" />
</svg>

固定色を currentColor に書き換えます。

<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  <path fill="currentColor" d="M12 3l9 7v11h-6v-6H9v6H3V10z" />
</svg>

呼び出し側では color を渡すだけで、テーマに応じて色が切り替わります。

import { useColorScheme } from "react-native";
import HomeIcon from "../assets/icons/home.svg";
 
export function HomeTab() {
  const scheme = useColorScheme();
  const tint = scheme === "dark" ? "#F2F2F7" : "#1C1C1E";
  return <HomeIcon width={24} height={24} color={tint} />;
}

複数の色を持つイラスト系SVGでは、変えたい部分だけ currentColor にして、変えたくない差し色は固定色のまま残す、という使い分けができます。アイコンのように単色で扱いたいものは全パスを currentColor に統一しておくと、後から配色を変える際に一箇所で済みます。

どちらの方法を選ぶか

状況向いている方法
デザイナー書き出しのSVGを大量に使う解決策1(transformer で import)
数点だけ・動的に形を変えたいreact-native-svgSvg / Path で手書き
色をテーマに追従させたい解決策2(currentColor)を併用

私自身は、タブバーやリスト行の小さなアイコンは transformer で .svg を直接読み込み、色は currentColor に統一する形に落ち着きました。デザインの差し替えが .svg ファイルの入れ替えだけで済むので、運用がとても軽くなります。

予防策

同じ落とし穴を避けるために、私は次の3点を最初に固めるようにしています。

まず、プロジェクトを立ち上げた初日に metro.config.js と型定義を入れてしまうこと。後から入れると「なぜか表示されない」の切り分けに時間を取られます。

次に、SVGを追加したら必ず一度は 開発ビルド(Expo Go ではなく) で確認すること。Expo Go は同梱ライブラリの都合で挙動が異なることがあり、Expo Go で動いたことは本番で動く保証になりません。

最後に、設定を触ったら --clear を癖にすること。SVG 周りの「直したのに直らない」の大半は、Metro のキャッシュが古い解決結果を握っていることが原因でした。

参考リンク

小さなアイコンひとつでも、表示の仕組みを理解しておくと後々の運用がぐっと楽になります。同じところで足止めされている方の助けになれば幸いです。お読みいただきありがとうございました。

シェア

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

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

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

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

関連記事

開発ツール2026-05-25
Rork で targetSdkVersion 35 にしたら Android のレイアウトが下まで埋まる問題の直し方
Android 15 (API 35) で強制されるエッジ・トゥ・エッジ表示によって、Rork で生成したアプリの下部タブやヘッダーがシステムバーに食い込む問題を、react-native-edge-to-edge と useSafeAreaInsets を使って実装パターン別に解決します。
開発ツール2026-05-03
Rork で「Unable to resolve module」が出たときに最初に確認する5つのこと
Rork や React Native / Expo 開発でよく出る「Unable to resolve module」エラーの原因を5パターンに整理し、確認順序とコマンドつきで素早く解決する手順を紹介します。
開発ツール2026-04-24
Metro bundlerが固まる・Fast Refreshが効かない時の診断手順
Rorkで生成したExpoアプリでMetro bundlerが固まる、Fast Refreshが反映されない——そんな時に順番にチェックすべき診断ステップと、安全なリセット手順をまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →