ガイド

iPhone アプリ2026年11月5日約12分

辻直哉

Capacitor とは、Web の画面をそのまま iPhone アプリの中で動かすための道具です。この記事では、Next.js で作ったサイトを Capacitor で iPhone アプリにし、Mac のシミュレーターで動かすところまで進めます。私が記録アプリ「ツモル」を App Store に出したときの設定とコマンドを、そのまま載せています。

この記事でできること
かかる時間
必要なもの
確認した環境

Capacitor とは

Capacitor は、Web の画面を表示する部品(iPhone では WKWebView)をアプリの中に置き、そこで自分の Web アプリを動かす仕組みです。公式は「Web アプリのための、複数の OS で動くネイティブの実行環境」と説明しています。

ふつうの Web サイトと違うのは、画面の JavaScript から iPhone の機能を呼べることです。ツモルでは「端末の中で時刻を予約する通知」のために入れました。ホーム画面に追加する Web アプリ(PWA)では、通知はサーバーから送る形しか取れません。

Cordova・Ionic との違い

  • Cordova:Capacitor より前からある、同じ考え方の道具です。公式は「考え方はとても近い」と書いています。Capacitor は Cordova のプラグインも使えますが、使えないものもあり、npx cap sync が飛ばします(公式の Cordova プラグインのページ)。
  • Ionic:Capacitor を作っているチームの名前であり、同じチームが出している画面の部品集(Ionic Framework)の名前でもあります。Capacitor は Ionic Framework が無くても使えます。React でも Vue でも、Next.js でもかまいません。

向いているアプリ・向かないアプリ

向いているもの

  • すでに Web 版があり、同じコードで iPhone 版も出したいアプリ
  • 記録・ToDo・予定のように、画面の操作が中心のアプリ
  • 通知や振動など、Web では足りない機能を少しだけ足したいアプリ

ツモルは Web 版と iPhone 版を同じコードから作り、iPhone 版にだけ通知(@capacitor/local-notifications)、振動(@capacitor/haptics)、広告(@capacitor-community/admob)を足しています。

向かないもの

  • 3D のゲームなど、描く処理が重いアプリ
  • Web サイトを包んだだけで、アプリならではの機能が無いもの

2つ目は審査の問題です。Apple の審査の決まり 4.2 は「包み直した Web サイト以上の機能・内容・画面」を求めています。私は KOMARO(日程調整のアプリ)を出す前にここを心配していましたが、KOMARO もツモルも 4.2 での差し戻しはありませんでした。ツモルは最初から通知を入れ、審査メモに「圏外でも記録できる」ことを書いています。

Next.js のサイトを iPhone アプリにする手順

1. Next.js を静的に書き出す

Capacitor はアプリの中に「HTML と JavaScript のファイル一式」を入れて開きます。Next.js には、サーバー無しで開けるファイルに書き出す機能(静的書き出し)があります。next.config.ts に output: "export" を書くと、next build で out フォルダができます。

ツモルでは、Web の本番(Vercel)はそのままにして、アプリ用のときだけ書き出すように切り替えています。

// next.config.ts
import type { NextConfig } from "next";

const forApp = process.env.TSUMORU_TARGET === "app";

const nextConfig: NextConfig = {
  ...(forApp ? { output: "export", pageExtensions: ["tsx"] } : {}),
};

export default nextConfig;

pageExtensions: ["tsx"] は、API のファイル(route.ts)を書き出しから外すためです。書き出しでは、リクエストを読む API、Cookie、リダイレクト、Server Actions、next/image の既定の画像最適化などが使えません(Next.js 公式の静的書き出しのページに一覧があります)。API が要る場合、アプリからは本番の住所の API を呼びます。

  1. next.config.ts を上のように書き換える。
  2. TSUMORU_TARGET=app npx next build を流す(TSUMORU_TARGET の名前は自分のアプリに合わせて変えてかまいません)。
  3. out フォルダの直下に index.html ができたことを確かめる。
Finder で開いた out フォルダ。index.html と _next フォルダが並んでいる
Finder で開いた out フォルダ。index.html と _next フォルダが並んでいる

index.html には <head> が要ります。無いとプラグインが動きません(Capacitor 公式)。Next.js の書き出しなら入っています。

2. Capacitor を入れる

プロジェクトの一番上のフォルダで、次を流します(Capacitor 公式の手順)。

npm i @capacitor/core
npm i -D @capacitor/cli
npx cap init

npx cap init はアプリの名前と ID を聞いてきます。ID は iPhone の「Bundle ID」になるもので、自分のドメインを逆にした形(例:app.tsumoru)にします。Apple の説明では、ビルドをアップロードしたあとは Bundle ID を変えられません。ここで決めておきます(App Store Connect ヘルプ)。

できた capacitor.config.ts の webDir を、書き出し先の out にします。ツモルの設定はこれだけです。

// capacitor.config.ts
import type { CapacitorConfig } from "@capacitor/cli";

const config: CapacitorConfig = {
  appId: "app.tsumoru",
  appName: "ツモル",
  webDir: "out",
};

export default config;

3. iOS のプロジェクトを作る

npm i @capacitor/ios
npx cap add ios

ios フォルダができ、中に Xcode のプロジェクトが入ります。Capacitor 8 では、iOS の部品の管理に Swift Package Manager を使うのが標準です。前の版で使っていた CocoaPods は --packagemanager CocoaPods を付けたときだけ使います(公式の環境の手順)。CocoaPods を使わないなら Homebrew も要りません。

Finder で開いた ios/App フォルダ。App.xcodeproj と CapApp-SPM が見える
Finder で開いた ios/App フォルダ。App.xcodeproj と CapApp-SPM が見える

4. 書き出した画面をアプリへ入れる

npx cap sync ios

out の中身が ios/App/App/public へ写され、プラグインも組み込まれます。画面を直したら、毎回「書き出し → sync」をやり直します。 ツモルでは1つのコマンドにまとめています。

"scripts": {
  "build:app": "TSUMORU_TARGET=app next build && cap sync ios"
}
npm run build:app

5. Xcode で開いてシミュレーターで動かす

npx cap open ios
  1. Xcode が開いたら、上の真ん中にある端末の選択から、シミュレーター(例:iPhone 17)を選ぶ。
  2. 左上の再生ボタン(▶)を押す。
  3. シミュレーターが立ち上がり、自分のアプリが開くのを待つ。
Xcode の上の端末の選択を開き、シミュレーターの一覧が出ている
Xcode の上の端末の選択を開き、シミュレーターの一覧が出ている
シミュレーターでツモルの ToDo の画面が開いている
シミュレーターでツモルの ToDo の画面が開いている

Xcode を開かずに npx cap run ios でも動かせます。

実機・ストアに出すときの注意

自分の iPhone で動かす

  1. iPhone を Mac につなぐ。
  2. Xcode の左の一覧で「App」を選び、「Signing & Capabilities」を開く。
  3. 「Team」に自分の Apple アカウントを選ぶ。
  4. 端末の選択で自分の iPhone を選び、再生ボタンを押す。
Xcode の Signing & Capabilities で Team を選ぶ欄
Xcode の Signing & Capabilities で Team を選ぶ欄

Apple Developer Program に入っていない無料のアカウント(Xcode では「Personal Team」と出ます)でも、自分の iPhone で動かせます。ただし、入れたアプリは7日で期限が切れ、登録できる端末は3台までです(Apple の比較表)。期限が切れたら、もう一度ビルドして入れ直します。

Xcode から iPhone に入れるときは、iPhone の「設定」→「プライバシーとセキュリティ」→「デベロッパモード」をオンにします。オンにすると再起動を求められ、再起動のあとに「有効にする」を押してパスコードを入れます。この項目は、Mac とつないだことがある iPhone にだけ出ます(Apple の説明)。

ストアに出す前に確かめること

  • server.url で本番のサイトを読む作りにしない。 Capacitor の設定には、アプリの中で外の住所を開く server.url がありますが、公式は「開発中の再読み込み用で、本番に使うものではない」と書いています。KOMARO の iPhone 版は今もこの形で出していますが、これから作るなら画面を同梱する形を勧めます。
  • アプリならではの機能を1つ入れる。 審査の決まり 4.2 への備えです。ツモルの通知、KOMARO の圏外の案内画面がこれにあたります。
  • Web を直してもアプリは変わらない。 画面を同梱しているので、アプリに届けるには書き出してストアに出し直します。
  • Capacitor を新しい版に上げておく。 2026年10月、@capacitor/ios 8.5.0 に重大な脆弱性の勧告(GHSA-rvm3-566m-v7fv)が出ました。ツモルは 8.5.3 に上げてから審査に出し直しています。npm audit で確かめられます。
  • 広告や分析を入れたら、App Store Connect の「App のプライバシー」を直す。 ツモルは AdMob を入れたとき、「デバイスID」と「広告データ」を足してから出しました。

審査に出す手順はApp Store にアプリを出す手順にまとめています。

圏外でも開けるようにするには

画面をアプリに同梱すれば、起動するときに通信しないので、電波の無い場所でも開けます。ツモルは最初、本番を読みながら Service Worker(一度読んだ画面を端末に取っておく仕組み)で圏外に備えていましたが、広告と両立しませんでした。最後は同梱に切り替えて、圏外と広告の両方を取っています。

同梱にすると、画面の住所が https://... から capacitor://localhost に変わります。そのため、端末に保存した記録の引き継ぎ、API の呼び先、ログインのメールの戻り先を直す必要がありました。この話は圏外でも開けるアプリにする方法に書いています。

よくあるエラーと直し方

エラーの文原因直し方
(エラーは出ず、ボタンを押しても何も起きない)server.url で外のサイトを読み、Capacitor が2つ動いている注入された Capacitor.Plugins だけを使う。または画面を同梱する
日本語が全部「□」になる-apple-system だけでは日本語の書体に切り替わらない日本語用の書体(ヒラギノなど)を名前で指定する
別の画面で読み直すとトップの画面が出る拡張子の無い住所を Capacitor が index.html として返す同じ名前の .html を返す振り分けを iOS 側に書く
ネットワークに接続できませんserver.url で本番を読んでいて、通信できない画面を同梱する。読む作りのままなら server.errorPath で同梱の案内画面を出す
Page "/…/[id]" is missing "generateStaticParams()" so it cannot be used with "output: export" config.住所に変数を含む画面([id])に、書き出す住所の一覧が無いgenerateStaticParams() で書き出す住所を決める

よくある質問

Capacitor と Cordova、今から使うならどちらですか。

私は Capacitor を使っています。どちらも Web の画面をアプリの中で動かす道具ですが、Capacitor は Cordova のプラグインの多くも使えます。Cordova から Capacitor へ移る手順も公式にあります。

Capacitor を使うには Ionic が必要ですか。

要りません。Capacitor は Ionic のチームが作っていますが、画面は React・Vue・Next.js など何で作ってもかまいません。ツモルは Next.js と Tailwind CSS だけで、Ionic の部品は使っていません。

Next.js の API(Route Handlers)はアプリの中で動きますか。

書き出したアプリの中では動きません。リクエストを読む API はサーバーが要るためです。ツモルでは API を Vercel の本番に置いたまま、アプリからはその住所を呼んでいます。本番の API 側では、アプリの住所(capacitor://localhost)からの呼び出しを通す設定(CORS)を足しました。

Windows でも iPhone アプリを作れますか。

iPhone アプリをビルドするには Mac が要ります(Capacitor 公式の環境の手順)。Capacitor そのものは Windows でも入りますが、Xcode が Mac にしか無いためです。

書いた人