メインコンテンツへスキップ

Capacitor Google Mapsプラグインの代替案(2026年)

@capacitor/google-maps プラグインの代替案を比較:MapLibre、Leaflet、Google Maps JS、ネイティブオプションについて、code、コスト、使い分けを解説します。

Capacitor のマッププラグインを比較するための Capgo プラグイン図解

Capacitor の Google Maps 代替案が必要な場合、現実的な選択肢は3つあります:公式 @capacitor/google-maps プラグインを使い制限内で対応するか、MapLibre GL JS や Leaflet などの JavaScript ライブラリを使用して WebView 内でマップを描画するか、あるいは別の SDK ベースのネイティブマッププラグインを使用するかです。Capgo は独自のマップ描画プラグインを提供していないため、このガイドでは各オプションを中立的に比較し、どのマップとも相性の良い Capgo プラグイン(ナビゲーションの引き継ぎ、ジオコーディング、バックグラウンド位置情報)を紹介します。

なぜ開発者は @capacitor/google-maps 以外の選択肢を検討するのか

公式プラグイン(Capacitor 8 用のバージョン 8)は、iOS と Android ではネイティブの Google Maps SDK を、Web では Google Maps JavaScript API を埋め込みます。動作はしますが、以下の点が繰り返し問題になります。

全プラットフォームで課金が有効な Google Cloud アカウント

このプラグインを使用するには、Android、iOS、Web のすべてで、課金が有効な Google Cloud アカウントに紐付いた API キーが必要です。ネイティブモバイルでのマップロードに対する Google の料金体系は比較的余裕がありますが、それでも課金設定を行い、キーをプラットフォームごとに制限し、クォータを監視する必要があります。Web でのマップロードや Places、Directions などのサービスは、無料枠を超えると従量課金されます。2025 年に料金モデルが変わっているため、導入前に Google Maps Platform の最新の料金ページを確認してください。

Android ではマップが WebView の背後に描画される

iOS ではマップビューが WebView のスクロールビュー内に配置されます。Android では WebView 全体の下にレンダリングされ、プラグインがそれを追従させるように <capacitor-google-map> 要素を移動させます。その上にあるすべてのレイヤーは透明でなければなりません:

/* Required on Android with @capacitor/google-maps */
html,
body,
ion-content,
ion-content::part(background) {
  background: transparent !important;
  --background: transparent;
}

これが「マップが真っ白になる」という問題の最大の原因です。また、HTML がネイティブビューの上に重なるため、カスタムオーバーレイ、モーダル、ページ遷移の実装も難しくなります。

マーカーは追加・削除はできるが、更新はできない

API には addMarker, addMarkers, removeMarker と removeMarkersがありますが、 updateMarker車両の位置をリアルタイムで表示する場合、更新のたびに要素の削除と追加を繰り返す必要があり、画面のちらつきやブリッジ通信のコストが発生します。

ネイティブではスタイルと機能に制限あり

例えば、以下のようなWebのみ対応のオプションもあります: mapId クラウドベースのスタイリング、および region と languageマーカー、クラスタリング、ポリライン、ポリゴン、円、タイルオーバーレイ、カメラ制御、クリックリスナーなどが利用可能です。ただし、全プラットフォームでデータ駆動型のスタイリングやヒートマップ、3Dビルディングを同様に実現しようとすると、制限に直面することになります。

選択肢の概要

オプション レンダリング API のキーが必要 タイルソース 最適な用途
@capacitor/google-maps ネイティブ SDK(Android、iOS)、WebではJS はい、課金有効 Google Googleのデータとネイティブパフォーマンスを求めるアプリ
MapLibre GL JS WebView内のWebGL タイルプロバイダーに依存 任意のベクトルタイルソース、セルフホスト可能 カスタムスタイルの地図、オフライン寄り、ベンダーロックインなし
Leaflet WebView内のDOMとcanvas タイルプロバイダーに依存 ラスタタイル(OSMベースなど) シンプルな地図、軽量なbundle、豊富なプラグイン
WebView内のGoogle Maps JS API GoogleのJSレンダラー はい Google 全プラットフォームで同じGoogleの見た目、JS機能をフル搭載
Native MapLibreまたはMapboxプラグイン Native SDK 用途による 任意 / Mapbox 大量のデータ、長時間セッション、ネイティブジェスチャー

唯一の正解はありません。データ量、スタイリングの要件、および特定のベンダーへの依存度によって最適な選択肢は変わります。

案1: WebViewでのMapLibre GL JS

MapLibre GL JSはMapbox GL JS v1のオープンソースフォークです。WebGLでベクトルタイルを描画し、WKWebViewやAndroid System WebViewでもスムーズに動作します。Googleのデータが不要であれば、最も柔軟な選択肢となります。

bun add maplibre-gl
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';

const map = new maplibregl.Map({
  container: 'map',
  style: 'https://your-tile-provider.example.com/styles/streets/style.json',
  center: [2.3522, 48.8566], // [lng, lat]
  zoom: 12,
});

map.addControl(new maplibregl.NavigationControl(), 'top-right');

// A marker you can move without remove/add
const courier = new maplibregl.Marker({ color: '#1d4ed8' })
  .setLngLat([2.35, 48.85])
  .addTo(map);

export function moveCourier(lng: number, lat: number) {
  courier.setLngLat([lng, lat]);
}

GeoJSONレイヤー、データ駆動型スタイリング、ルートラインをファーストクラスでサポート:

map.on('load', () => {
  map.addSource('route', {
    type: 'geojson',
    data: {
      type: 'Feature',
      properties: {},
      geometry: {
        type: 'LineString',
        coordinates: [
          [2.3522, 48.8566],
          [2.3376, 48.8606],
          [2.2945, 48.8584],
        ],
      },
    },
  });
  map.addLayer({
    id: 'route-line',
    type: 'line',
    source: 'route',
    paint: { 'line-color': '#2563eb', 'line-width': 5 },
  });
});

注意点:

  • タイルソースが必要です。商用のベクトルタイルホストを利用するか、OpenStreetMapのデータから生成したタイルをセルフホストする選択肢があります。なお、OpenStreetMapのパブリックタイルサーバーには利用ポリシーがあり、アプリからの大量のトラフィックは許可されていません。
  • タイルプロバイダーが規定するクレジット表記(attribution)は必ず表示してください。
  • プレーンなWeb code なので、ブラウザプレビューでも同じマップが動作し、開発をスピードアップできます。

案2: Leaflet

Leafletは軽量で成熟したライブラリです。数百個程度のマーカー、ラスタタイル、シンプルなインタラクションを伴うマップに適しています。

bun add leaflet
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';

const map = L.map('map').setView([48.8566, 2.3522], 13);

L.tileLayer('https://tiles.example.com/{z}/{x}/{y}.png', {
  maxZoom: 19,
  attribution: '&copy; OpenStreetMap contributors',
}).addTo(map);

L.marker([48.8584, 2.2945]).addTo(map).bindPopup('Eiffel Tower');

バンドルされたアプリでは、Leafletのデフォルトのマーカーアイコンのパスが壊れがちです。アイコン画像をインポートしてオプションを設定するか、 L.Icon.Default 独自のアイコンを使用してください。 L.divIcon.

案3: WebViewでのGoogle Maps JavaScript API

Googleのデータや見た目は必要だが、マップを他のHTML要素と同じように扱いたい場合は、ネイティブのSDKではなく、WebView内でMaps JavaScript APIをロードしてください。ネイティブ特有の滑らかさは多少損なわれ、マップのロードごとにWebの課金が発生しますが、マップIDによるクラウドスタイリングや高度なマーカー、データレイヤーなど、JSのAPIをフルに活用できます。

HTTPリファラーを使用してWebキーを制限してください。iOSでは、Capacitorはアプリを capacitor://localhost から提供し、Androidでは https://localhostから提供するため、それらのオリジンをキーの制限に追加して両方の動作を確認してください。

案4: 他のSDKで作られたネイティブプラグイン

コミュニティには、MapLibre NativeやMapbox SDKをラップしたNative wrapperが存在します。これらは、あらゆるタイルソースにおいてNativeなジェスチャーとパフォーマンスを提供します。選定の際は、Capacitor 8をサポートしているか、最新のリリースがあるか、iOS(最新のCapacitor 8 iOSプロジェクトのデフォルト)でSwift Package Managerをサポートしているか、そして必要なオーバーレイタイプをカバーしているかを確認してください。Nativeマッププラグインは、公式プラグインと同様のレイヤー構成のトレードオフがあります。マップはNative viewとして扱われるため、HTMLはそれを避けるようにレイアウトする必要があります。

@capacitor/google-maps を選ぶべきケース

  • Googleのベースマップ、Places、およびStreet Viewのデータが必要です。
  • マップはスクロールコンテンツ内の小さなカードではなく、フルスクリーンのビューとして使用します。
  • マーカーの移動には、削除と追加を繰り返すか、更新頻度が低い方法でも問題ありません。

継続して使用する場合は、CSSで透明度を設定し、 <capacitor-google-map> 要素に明示的なサイズを指定して、 destroy() ページを離れる際に呼び出し、 skipLibCheck: true における tsconfig.json プラグインのREADMEの指示に従って設定してください。

あらゆる地図と相性の良いプラグイン

地図の描画方法は様々ですが、これらの Capgo プラグインは、WebViewベースの地図では不可能なネイティブ機能を提供します。

ターンバイターンナビゲーションを任せる

ナビゲーション機能の構築はそれ自体が大きなプロジェクトです。多くのアプリでは、ユーザーが普段使っているナビアプリを起動する手法をとっています。 @capgo/capacitor-launch-navigator Apple Maps、Google Maps、Wazeなど、多くのサービスに対応しています:

import { LaunchNavigator, TransportMode } from '@capgo/capacitor-launch-navigator';

await LaunchNavigator.navigate({
  destination: [48.8584, 2.2945], // [lat, lng]
  options: { transportMode: TransportMode.DRIVING },
});

Webサービス不要のジオコーディング

@capgo/capacitor-nativegeocoder iOSとAndroidのプラットフォーム標準のジオコーダーを使用するため、デバイス上でGoogle APIキーを用意する必要はありません:

import { NativeGeocoder } from '@capgo/capacitor-nativegeocoder';

const { addresses } = await NativeGeocoder.reverseGeocode({
  latitude: 48.8584,
  longitude: 2.2945,
  maxResults: 1,
});
console.log(addresses[0]?.thoroughfare, addresses[0]?.locality);

const result = await NativeGeocoder.forwardGeocode({
  addressString: '5 Avenue Anatole France, Paris',
  maxResults: 1,
});
console.log(result.addresses[0]?.latitude, result.addresses[0]?.longitude);

Web環境では、プラグインはGoogleの API を使用するため、 apiKey オプションが追加されました。

バックグラウンドでもユーザーの位置を表示

フォアグラウンドでの「現在地(青いドット)」表示には、 @capacitor/geolocation これだけで十分です。アプリがバックグラウンドの状態でも追跡を継続したり、特定の場所に進入した際にイベントをトリガーしたりするには、 @capgo/background-geolocationを使用し、選択した地図に座標を渡してください。

Capacitor でのマップ関連トラブルシューティング

公式プラグインを使用した場合、Androidで地図が空白になる。 親要素の透明度が設定されていない。Chrome DevToolsで以下を確認してください: chrome://inspect 「 <html> 」と地図要素の間の

背景色がないか。 地図要素の高さが0になっている。地図コンテナには固有のサイズがないため、明示的な高さを設定するか、親要素に固定の高さを指定してflexレイアウトを使用してください。

AndroidでWebGLマップがぼやける、または動作が重い。 デバイスのSystem WebViewが最新か確認し、レイヤー数を減らしてください。ルート変更のたびにマップを作り直さず、一度作成したものを再利用しましょう。

リリースビルドでタイルが読み込まれない。 Content Security Policyとネットワークセキュリティ設定を確認し、タイルホストがHTTPSであることを確かめてください。

タイルスタイルのURLを変更するとマップが壊れる。 スタイルとタイルのURLは単なるJavaScriptの設定です。既存ユーザー向けのプロバイダー切り替えは、次の条件で可能です: Capgo Live Updatesアプリストアリリースなしで、ネイティブの code に変更がない限り。

判断方法

  • フルスクリーンマップでGoogleのデータとネイティブのパフォーマンスが必要なら、そのまま使い続ける。 @capacitor/google-maps.
  • カスタムスタイリング、Googleの課金が不要、HTMLのように動くマップが必要な場合:MapLibre GL JS。
  • マーカーを数個置くだけのシンプルなマップが必要なら:Leaflet。
  • スクロール可能なレイアウトでGoogle Mapsの見た目を実現したい場合:WebView内でGoogle Maps JS API を使用します。

どれを選んでも、早めに低スペックのAndroid端末でテストしてください。ネイティブの構成要素をさらに探すには、以下をご覧ください: Capgo プラグインディレクトリ.

Capacitor アプリ向けの Live Updates

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

最新のブログ記事

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