メインコンテンツへスキップ
チュートリアル

Capacitor 8 を使って Next.js アプリを iOS & Android に変換

Capacitor 8 を使って、既存の Next.js 15 Web アプリをネイティブの iOS/Android モバイルアプリに変換しましょう。静的エクスポートの設定、ネイティブプラグインの追加、アプリストアへのデプロイまでを解説する完全ガイドです。

Capacitor 8 を使って Next.js アプリを iOS & Android に変換

はじめに

Have an existing Next.js web application? In this guide, you’ll learn how to transform it into native iOS and Android mobile apps using Capacitor 8 — パフォーマンスが向上し、新機能が追加された最新バージョンです。

Capacitor は、既存の React コードベースを維持したまま、Web アプリをネイティブコンテナでラップし、カメラやファイルシステム、プッシュ通知などのデバイス API へのアクセスを可能にします。React Native とは異なり、コードを書き直す必要はありません。Next.js の code がそのまま動作します。

学習内容:

  • 既存の Next.js アプリを静的エクスポート用に設定する
  • 必須のネイティブプラグインを含む Capacitor 8 を追加する
  • iOS および Android シミュレーターでのビルドとテスト
  • 開発を高速化するライブリロードの有効化
  • iOS でよくあるレイアウトの問題(viewport、セーフエリア、横方向のオーバーフロー)の修正
  • Capgo Native Navigation と Transitions でネイティブに近い UI を実現する

ゼロから新しいプロジェクトを始めたい方は、こちらのガイドをご覧ください: Next.js モバイルアプリをゼロから構築する.

Next.js と Capacitor を使用するメリット

  • Code による再利用性: Next.js を使用すると、再利用可能なコンポーネントを作成し、Web アプリとモバイル アプリ間で code を共有できるため、開発時間と工数を削減できます。
  • パフォーマンス: Next.js は、サーバーサイドレンダリングや code splitting などのパフォーマンス最適化機能が組み込まれており、高速な読み込みとスムーズなユーザー体験を実現します。
  • ネイティブ機能: Capacitor を使用すると、カメラや位置情報などのデバイスのネイティブ機能にアクセスでき、機能豊富なモバイルアプリを構築できます。
  • 開発の簡素化: Capacitor を使えば、使い慣れた Web 技術でモバイルアプリの開発とテストができるため、学習コストを抑え、開発プロセスを効率化できます。

前提条件

始める前に、以下が準備されていることを確認してください:

  • Node.js 18+ インストール
  • 既存の Next.js 15+ アプリケーション
  • iOSプロファイリング (iOS開発用、macOSのみ)
  • デバッグ (Android開発用)

Next.jsアプリをモバイル向けに設定する

最初のステップは、Next.jsアプリを静的エクスポート用に設定することです。Capacitor でネイティブアプリにバンドルするには、静的なHTML/JS/CSSファイルが必要になります。

以下の next.config.js (または next.config.ts) ファイルを開き、エクスポート設定を追加します:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: {
    unoptimized: true,
  },
};

module.exports = nextConfig;

この output: 'export' この設定により、Next.js は静的 HTML ファイルを生成し、 images: { unoptimized: true } サーバーを必要とする Next.js の画像最適化を回避します。

重要: サーバーが必要な機能(API ルートや、データ取得を伴うサーバーコンポーネントなど)を使用している場合は、クライアントサイドの代替手段や外部 API を使用するようにリファクタリングする必要があります。

モバイル専用のスクリプトを以下に追加します: package.json:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "mobile": "bun run build && bunx cap sync",
    "mobile:ios": "bun run mobile && bunx cap open ios",
    "mobile:android": "bun run mobile && bunx cap open android"
  }
}

以下のコマンドを実行して、静的エクスポートをテストしてください:

bun run build

プロジェクトのルートに out フォルダが表示されるはずです。ここには、Capacitor がネイティブアプリに bundle するすべての静的ファイルが含まれています。

プロジェクトに Capacitor 8 を追加する

Next.js アプリをネイティブモバイルコンテナにパッケージングするには、以下の手順に従ってください:

  1. Capacitor core と CLI をインストールします:
bun add @capacitor/core
bun add -D @capacitor/cli
  1. よく使用する Capacitor プラグインをインストールします:
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/preferences

これらのプラグインは、以下の必須機能を提供します:

  • @capacitor/app・アプリのライフサイクルイベント(フォアグラウンド/バックグラウンド、URL)の制御
  • @capacitor/keyboard・モバイルにおけるキーボード挙動の制御
  • @capacitor/splash-screen: ネイティブのスプラッシュ画面を管理
  • @capacitor/preferences・キーバリューデータの永続的な保存
  1. プロジェクトの詳細で Capacitor を初期化します:
bunx cap init my-app com.example.myapp --web-dir out

置換する my-app アプリ名と com.example.myapp アプリID(逆ドメイン形式)を使用して。

  1. 以下を作成または更新: capacitor.config.ts 適切な設定を含むファイル:
import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.myapp',
  appName: 'my-app',
  webDir: 'out',
  plugins: {
    SplashScreen: {
      launchShowDuration: 2000,
      launchAutoHide: true,
      androidScaleType: 'CENTER_CROP',
      showSpinner: false,
      splashFullScreen: true,
      splashImmersive: true,
    },
  },
};

export default config;
  1. ネイティブプラットフォームのインストール:
bun add @capacitor/ios @capacitor/android
  1. ネイティブプラットフォームのフォルダを追加:
bunx cap add ios
bunx cap add android

Capacitor により、 ios と android ネイティブプロジェクトを含むフォルダがプロジェクトのルートに作成されます。

Androidプロジェクトをビルドするには、以下が必要です: デバッグ。iOSの場合は、以下を備えたMacが必要です: iOSプロファイリング.

  1. プロジェクトのビルドと同期:
bun run mobile

これにより、Next.jsプロジェクトをビルドして静的ファイルをネイティブプラットフォームと同期するカスタムスクリプトが実行されます。

ネイティブアプリのビルドとデプロイ

ネイティブモバイルアプリをビルドしてデプロイするには、以下の手順に従ってください。 iOSアプリを開発するには、 iOSプロファイリング のインストールが必要です。また、Androidアプリの場合は、 デバッグ のインストールが必要です。さらに、アプリをApp Storeで配布する場合は、iOS用にApple Developer Programへ、Android用にGoogle Play Consoleへの登録が必要になります。

  1. ネイティブプロジェクトを開く:

iOSの場合:

bun run mobile:ios

Androidの場合:

bun run mobile:android

または Capacitor CLI で直接実行:

bunx cap open ios
bunx cap open android
  1. アプリのビルドと実行:

android-studio-run

  • Android Studioでプロジェクトの準備が整うまで待ち、「Run」ボタンをクリックして、接続されたデバイスまたはエミュレータにアプリをデプロイします。 xcode-run

  • Xcodeで、実機にデプロイするためのSigningアカウントを設定します。初めての場合は、Xcodeのガイドに従って設定を進めてください(Apple Developer Programへの登録が必要です)。設定完了後、「Play」ボタンをクリックすると、接続されたデバイスでアプリが実行されます。

おめでとうございます!Next.jsウェブアプリをモバイルデバイスへのデプロイに成功しました。

nextjs-mobile-app
でもちょっと待ってください。開発中にもっと素早く行う方法があります...

Capacitor Live Reload

開発中は、Live Reloadを活用することで、変更内容をモバイルデバイスに即座に反映できます。この機能を有効にするには、以下の手順に従ってください:

  1. ローカルIPアドレスを確認してください:
  • macOSの場合は、ターミナルで次のコマンドを実行してください:

    ipconfig getifaddr en0
  • Windowsの場合は、以下を実行してください:

    ipconfig

    出力結果からIPv4アドレスを確認します。

  1. 以下のファイルを更新して、 capacitor.config.ts 開発サーバーを指すように:
import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.app',
  appName: 'my-app',
  webDir: 'out',
  server: {
    url: 'http://YOUR_IP_ADDRESS:3000',
    cleartext: true,
  },
};

export default config;

置換する YOUR_IP_ADDRESS ローカルIPアドレスに置き換えます(例: 192.168.1.100).

  1. 変更をネイティブプロジェクトに適用します:
bunx cap copy

この copy このコマンドは、プロジェクト全体を更新することなく、webフォルダと設定の変更内容のみをネイティブプロジェクトにコピーします。

  1. Android StudioまたはXcodeを使用して、デバイス上でアプリを再ビルドして実行してください。

これで、Next.jsアプリに変更を加えるたびに、モバイルアプリが自動的にリロードされ、その変更が反映されるようになります。

注意:新しいプラグインをインストールしたり、ネイティブファイルを変更したりした場合は、ネイティブプロジェクトの再ビルドが必要です。ライブリロードはwebの code の変更にのみ適用されるためです。

Capacitor プラグインの使用

Capacitor plugins を使えば、Next.js アプリからデバイスのネイティブ機能にアクセスできます。その使用方法を プラグインを共有 例として見ていきましょう:

  1. Share プラグインをインストールします:
bun add @capacitor/share
  1. 更新: pages/index.js Share プラグインを使用するためのファイル:
import Head from 'next/head';
import styles from '../styles/Home.module.css';
import { Share } from '@capacitor/share';

export default function Home() {
  const share = async () => {
    await Share.share({
      title: 'Open Youtube',
      text: 'Check new video on youtube',
      url: 'https://www.youtube.com',
      dialogTitle: 'Share with friends',
    });
  };

  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>
          Welcome to <a href="https://nextjs.org">Capgo!</a>
        </h1>

        <p className={styles.description}>
          <h2>Cool channel</h2>
          <button onClick={() => share()}>Share now!</button>
        </p>
      </main>
    </div>
  );
}
  1. 変更内容をネイティブプロジェクトに同期します:

先ほど説明したように、新しいプラグインをインストールするときは、sync 操作を行ってからアプリをデバイスに再デプロイする必要があります。これを行うには、次のコマンドを実行してください:

bun run mobile

または、再ビルドせずに同期するだけなら:

bunx cap sync
  1. アプリを再ビルドしてデバイスで実行します。

これで、「Share now!」ボタンをクリックすると、ネイティブの共有ダイアログが表示され、他のアプリとコンテンツを共有できるようになります。

next-capacitor-share
次に、Capgo のナビゲーションとトランジションを活用して、iOS と Android でよりネイティブに近い操作感を実現できます。また、横方向のオーバーフローやセーフエリアの欠けといった、iOS 特有のレイアウト問題も解決可能です。 ## Capgo Native Navigation と Transitions によるネイティブな UI

私は長年、 Ionic クロスプラットフォームアプリの開発には適していますが、すでに利用している環境がある場合、Next.js との統合は無理があり、あまりメリットはありません。 Tailwind CSS 4.

Next.js + Capacitor アプリでネイティブなモバイル体験を実現するには、Konsta UI のような Web 専用の UI キットではなく、Capgo プラグインを使用してください:

  • @capgo/capacitor-native-navigation — ネイティブの navbar、iOS 用の Liquid Glass tab bar、Android 用のブラー付き tab bar スタイル。 Next.js ルーターがルートの状態を保持し、プラグインがネイティブの UI 要素(chrome)を制御します。
  • @capgo/capacitor-transitions — Ionic UI を導入することなく、WebView レイヤーで Ionic スタイルのページ遷移や iOS のエッジスワイプバックを実現します。

両方をインストールしてください:

bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync

CSSのinsetモードを使用してネイティブナビゲーションを設定し、Webコンテンツがネイティブバーと重ならないようにします:

import { NativeNavigation } from '@capgo/capacitor-native-navigation';

await NativeNavigation.configure({
  contentInsetMode: 'css',
  animationDuration: 360,
  glass: {
    effect: 'liquidGlass',
  },
});

Liquid Glassタブバーを実装します(iOSはシステム標準のレンダリングを使用し、AndroidはぼかしをかけたWebViewバックドロップを使用します):

await NativeNavigation.setTabbar({
  selectedId: 'home',
  labelVisibilityMode: 'labeled',
  icons: true,
  colors: { dynamic: true },
  tabs: [
    { id: 'home', title: 'Home', icon: { svg: '...' } },
    { id: 'settings', title: 'Settings', icon: { svg: '...' } },
  ],
});

await NativeNavigation.addListener('tabSelect', ({ id }) => {
  router.push(`/${id}`);
});

アプリシェルにネイティブのページ遷移を追加します:

import '@capgo/capacitor-transitions';
import { initTransitions, setDirection, setupRouterOutlet } from '@capgo/capacitor-transitions/react';

initTransitions({ platform: 'auto' });

ルーティングされたページを cap-router-outlet, cap-pageや cap-content、そして呼び出します setDirection('forward') または setDirection('back') の前に router.push() または router.back()でラップします。ネイティブナビゲーションがその領域を制御している場合、Web側のヘッダーやフッターを重複して作成しないでください。

ガイドの全文はこちら: @capgo/capacitor-native-navigation の活用 と @capgo/capacitor-transitions の活用.

Tailwind によるセーフエリア対応

Tailwind CSS でデバイスのセーフエリアを扱うには、以下を使用します: @capgo/tailwind-capacitor ( tailwind-capacitor として npm で公開)。これは、 safe-areas ユーティリティや Capacitor と相性の良いその他の Tailwind プラグインを提供します:

bun add -D tailwind-capacitor

では styles/globals.css:

@import 'tailwindcss';
@plugin "@capgo/tailwind-capacitor/platform";
@plugin "@capgo/tailwind-capacitor/safe-areas";

次のようなユーティリティを使用します: pt-safe, pb-safeや px-safe 手作業でばらまくのではなく env(safe-area-inset-*) 手動で行っています。このプロジェクトは活発に開発が進められています。Next.jsのセットアップで足りないものがあれば、 GitHub でPRを作成してください.

iOSのレイアウト問題を修正(ビューポート、セーフエリア、横方向のオーバーフロー)

iOSでコンテンツが切れて見えたり、ずれて見えたり、横スクロールが発生したりする場合は、さらに追加するだけでも、 overflow-x: hidden viewportタグを調整するだけでも通常は解決しません。以下のチェックを順番に確認してください。

viewport メタタグが正しく適用されているか確認する

App Router (app/): export viewport と app/layout.tsx:

import type { Viewport } from 'next';

export const viewport: Viewport = {
  width: 'device-width',
  initialScale: 1,
  viewportFit: 'cover',
};

Pages Router (pages/): viewportのmetaタグはここに配置します pages/_app.tsxではなく、 _document.tsx (Next.jsでは、viewportの挙動に関する _document.tsx タグの適用方法が想定と異なる場合があります。)

iOSのセーフエリアは1つのルートラッパーだけで処理する

単一のアプリシェルを作成し、そこにセーフエリアのパディングを適用してください — 複数のネストしたコンポーネントではなく:

html,
body,
#__next {
  width: 100%;
  min-height: 100%;
  margin: 0;
  padding: 0;
  overflow-x: hidden;
}

* {
  box-sizing: border-box;
}

.app-shell {
  min-height: 100dvh;
  width: 100%;
  padding-top: env(safe-area-inset-top);
  padding-right: env(safe-area-inset-right);
  padding-bottom: env(safe-area-inset-bottom);
  padding-left: env(safe-area-inset-left);
}

すべてのページコンテンツを以下でラップします: .app-shellヘッダー、モーダル、レイアウトラッパーで safe-area のパディングが重複すると、UI が欠けたり、逆に大きすぎたりすることがよくあります。

を使用すると、 @capgo/tailwind-capacitor同じパディングを次のようなユーティリティで表現できます: pt-safe pb-safe px-safe その単一のシェル上で。

Capacitor iOS を設定 contentInset まで never 最初に

では capacitor.config.ts、native inset を無効にすることを推奨し、CSS(または Native Navigation のもの contentInsetMode: 'css')に safe area を任せる:

const config: CapacitorConfig = {
  appId: 'com.example.myapp',
  appName: 'my-app',
  webDir: 'out',
  ios: {
    contentInset: 'never',
  },
};

Capacitor の自動コンテンツ inset と CSS を混在させると env(safe-area-inset-*) paddingが原因で、余白が二重に見えることがよくあります。

実際にオーバーフローしている要素を特定する

主な原因は、以下の要素を使用している場合です: 100vwTailwind、 w-screen固定ピクセル幅、または大きな min-width.

Safari Web Inspectorで以下を実行してください:

[...document.querySelectorAll('*')]
  .filter(el => el.scrollWidth > document.documentElement.clientWidth)
  .map(el => ({
    el,
    tag: el.tagName,
    class: el.className,
    scrollWidth: el.scrollWidth,
    clientWidth: document.documentElement.clientWidth,
  }));

Tailwindを使用する場合は、可能な限り w-screen を使用して w-full 置き換えてください。水平方向のオーバーフロー問題の多くは 100vw / w-screen、重複したセーフエリアのパディング、または固定幅のコンテナに起因し、viewportのmetaタグ自体が原因ではありません。

パフォーマンスの最適化

Next.js と Capacitor アプリのパフォーマンスを最大限に引き出すために、以下のベストプラクティスを検討してください:

  • 不要な依存関係やアセットを削除して、アプリのサイズを最小限に抑えます。
  • 画像やその他のメディアファイルを最適化し、読み込み時間を短縮します。
  • コンポーネントやページに lazy loading を実装し、初期ロードのパフォーマンスを向上させます。
  • Next.js の server-side rendering (SSR) を活用して、アプリの読み込み速度と SEO を向上させます。
  • Capacitor の web view キャッシュやアプリの bundling といった組み込みの最適化機能を活用します。

まとめ

Capacitor 8 を使用して、既存の Next.js ウェブアプリケーションを iOS および Android のネイティブアプリへの変換に成功しました。ウェブのコードベースがそのままモバイルデバイス上でネイティブに動作し、デバイス API へのアクセスも可能になります。

達成したこと:

  • Next.jsを静的エクスポート用に設定
  • 必須プラグイン入りの Capacitor 8 を追加
  • iOSとAndroidシミュレータ向けにビルドしてデプロイ
  • 開発用にライブリロードを有効化
  • iOSでよくあるレイアウト問題(viewport、safe area、overflow)を修正
  • Capgo Native NavigationとTransitionsでネイティブ感のあるUIを追加

次のステップ:

  • セットアップ Capgo App Storeへの再申請なしでOTAアップデートを実現
  • Camera、Geolocation、Push Notificationsなどのネイティブプラグインをさらに追加
  • 本番環境用のアプリアイコンとスプラッシュ画面の設定
  • App StoreとGoogle Playへの申請準備

新規プロジェクトを始めるなら、こちらを Next.js モバイルアプリをゼロから構築する のガイド付きウォークスルーをチェックしてください。

リソース

Capgo を使って、より高品質なアプリをより速く開発する方法を学びましょう。 無料アカウントに登録する を今すぐ作成してください。

次へ: Capacitor で Next.js アプリを iOS & Android に変換する 8

使用している場合 Capacitor 8 を使って Next.js アプリを iOS & Android に変換 ネイティブプラグインの作業を計画するには、次と連携してください: Capgo プラグインディレクトリ Capgo プラグインディレクトリのプロダクトワークフローについては、 Capgo による Capacitor プラグイン Capgo による Capacitor プラグインの実装詳細については、 プラグインの追加または更新 プラグインの追加または更新に関する実装詳細については、 Ionic Enterprise プラグインの代替案 Ionic Enterprise Plugin Alternatives のプロダクトワークフロー、および Capgo Native Build Capgo Native Builds のプロダクトワークフローについては、

Capacitor アプリ向けの Live Updates

Web レイヤーのバグが本番で発生したら、App Store の審査を何日も待たずに Capgo で修正を配信しましょう。ネイティブの変更は通常の審査フローに残したまま、ユーザーはバックグラウンドでアップデートを受け取れます。

最新のブログ記事

Capgoは、真にプロフェッショナルなモバイルアプリを作るために必要な最高のインサイトを提供します。