Zum Hauptinhalt springen
Anleitung

Build a Next.js Mobile App from Scratch with Capacitor 8

Step-by-step guide to creating a new Next.js 15 project and turning it into native iOS and Android mobile apps using Capacitor 8. Perfect for starting fresh with mobile-first development.

Artikelcredits

Martin Donadieu

Autoren

Valeria

Rezensent

Jordan

Herausgeber

Erstelle eine Next.js-Mobilanwendung von Grund auf mit Capacitor 8

Einführung

Möchtest du eine Mobilanwendung mit Next.js von vorne bis hinten erstellen? Diese Anleitung führt dich durch die Erstellung einer brandneuen Next.js 15-Projekt, das von Anfang an für Mobilgeräte konfiguriert ist, und verpackt es als native iOS- und Android-Apps mithilfe von Capacitor 8.

Mit dieser Anleitung hast du am Ende eine funktionierende Mobilanwendung, die auf Simulatoren läuft, die du weiterentwickeln und schließlich auf die App Store und Google Play veröffentlichen kannst.

Zeitaufwand: ~30 Minuten

Was du bauen wirst:

  • Ein neues Next.js 15-Projekt mit App Router
  • Statikexportkonfiguration für Mobilgeräte
  • Capacitor 8 mit wesentlichen Plugins
  • Nativ-Apps für iOS und Android
  • Live-Reload-Entwicklungsumgebung

Haben Sie bereits eine Next.js-Anwendung? Ihre Next.js-Anwendung auf Mobilgeräte umwandeln anstatt.

Voraussetzungen

Stellen Sie sicher, dass Sie diese installiert haben:

  • Node.js 18+ (überprüfen Sie mit node --version)
  • Bun Package-Manager (curl -fsSL https://bun.sh/install | bash)
  • Xcode (nur macOS, für iOS-Entwicklung)
  • Android Studio (für Android-Entwicklung)

Schritt 1: Erstellen Sie ein neues Next.js-Projekt

Beginnen Sie mit der Erstellung eines frischen Next.js 15-Projekts:

bunx create-next-app@latest my-mobile-app

Wenn Sie dazu aufgefordert werden, wählen Sie diese Optionen:

  • TypeScript: Ja (empfohlen)
  • ESLint: Ja
  • Tailwind CSS: Ja (empfohlen für mobile Stile)
  • src/ Verzeichnis: Ja
  • App Router: Ja (empfohlen)
  • Import-alias: Standard (@/*)

Navigiere zu deinem Projekt:

cd my-mobile-app

Schritt 2: Konfiguriere Next.js für statische Exportierung

Capacitor erfordert statische HTML/JS/CSS-Dateien. Konfiguriere Next.js für statische Exportierung, indem du next.config.ts:

import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  output: 'export',
  images: {
    unoptimized: true,
  },
  // Ensure trailing slashes for proper routing in Capacitor
  trailingSlash: true,
};

export default nextConfig;

Warum diese Einstellungen?

  • output: 'export' — Erzeugt statisches HTML anstatt eine Node.js-Server zu erfordern
  • images: { unoptimized: true } — Deaktiviert die Next.js-Bildoptimierung (erfordert einen Server)
  • trailingSlash: true — Stellt sicher, dass die Routing in der nativen WebView ordnungsgemäß funktioniert

Schritt 3: Hinzufügen von mobilen Skripten

Aktualisieren Sie Ihr package.json mit mobilen Entwicklungs-Skripten:

{
  "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"
  }
}

Testen Sie die Veröffentlichung:

bun run build

Sie sollten ein Verzeichnis mit Ihren statischen Dateien sehen. out Schritt 4: Installieren Sie __CAPGO_KEEP_0__ 8

Installieren Sie die Kern-Pakete von Capacitor:

Install the Capacitor core packages:

bun add @capacitor/core
bun add -D @capacitor/cli

Was diese Plugins tun:

bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/status-bar @capacitor/preferences

@__CAPGO_KEEP_0__/app

  • @capacitor/app — Lebenszyklusereignisse der App (Vordergrund/Hintergrund, tiefere Links)
  • @capacitor/Tastatur — Steuere die Tastaturverhalten
  • @capacitor/Splashbildschirm — Kontrolle des nativen Splashbildschirms
  • @capacitor/Statusleiste — Stile die Geräte-Statusleiste
  • @capacitor/Einstellungen — Schlüssel-Wert-Speicherung (wie localStorage, aber nativ)

Schritt 5: Initialisiere Capacitor

Initialisiere Capacitor mit Ihren Projekt-Daten:

bunx cap init "My Mobile App" com.example.mymobileapp --web-dir out

Ersetzen:

  • "My Mobile App" mit Ihrem App-Bezeichner
  • com.example.mymobileapp mit Ihrer App-ID (Umkehrung der Domänennotation)

Dies erstellt capacitor.config.ts. Aktualisieren Sie es mit Plugin-Konfiguration:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.mymobileapp',
  appName: 'My Mobile App',
  webDir: 'out',
  plugins: {
    SplashScreen: {
      launchShowDuration: 2000,
      launchAutoHide: true,
      androidScaleType: 'CENTER_CROP',
      splashFullScreen: true,
      splashImmersive: true,
    },
    Keyboard: {
      resize: 'body',
      resizeOnFullScreen: true,
    },
    StatusBar: {
      style: 'light',
    },
  },
};

export default config;

Schritt 6: Hinzufügen von Native Plattformen

Installieren Sie die Plattform-Pakete:

bun add @capacitor/ios @capacitor/android

Erstellen Sie die native Projekte:

bunx cap add ios
bunx cap add android

Dies erstellt ios und android Verzeichnisse, die die native Projekte enthalten.

Schritt 7: Erstellen und Ausführen

Bauen Sie Ihr Projekt und synchronisieren Sie es mit den native Plattformen:

bun run mobile

Öffnen Sie in iOS Simulator:

bun run mobile:ios

Oder Android-Emulator:

bun run mobile:android

In Xcode (iOS):

  1. Wählen Sie einen Simulator aus dem Geräte-Auswahlfeld
  2. Klicken Sie auf die Play-Taste oder drücken Sie Cmd + R

In Android Studio:

  1. Warten Sie, bis Gradle fertig ist, die Dateien zu synchronisieren
  2. Wählen Sie einen Emulator aus dem Geräte-Auswahlfeld
  3. Klicken Sie auf die Run-Taste oder drücken Sie Shift + F10

Schritt 8: Live Reload einrichten

Für eine schnellere Entwicklung aktivieren Sie Live Reload, damit Änderungen sofort auf Ihrem Gerät erscheinen.

  1. Finden Sie Ihre lokale IP-Adresse:
# macOS
ipconfig getifaddr en0

# Windows
ipconfig
  1. EntwicklungsCapacitor-Konfiguration erstellen. Hinzufügen zu capacitor.config.ts:
import type { CapacitorConfig } from '@capacitor/cli';

const devConfig: CapacitorConfig = {
  appId: 'com.example.mymobileapp',
  appName: 'My Mobile App',
  webDir: 'out',
  server: {
    url: 'http://YOUR_IP_ADDRESS:3000',
    cleartext: true,
  },
  plugins: {
    // ... same plugin config
  },
};

const prodConfig: CapacitorConfig = {
  appId: 'com.example.mymobileapp',
  appName: 'My Mobile App',
  webDir: 'out',
  plugins: {
    // ... same plugin config
  },
};

const config = process.env.NODE_ENV === 'development' ? devConfig : prodConfig;

export default config;
  1. Entwicklungs-Server starten und Konfiguration auf native übertragen:
bun run dev &
NODE_ENV=development bunx cap copy
  1. Erneutes Bauen in Xcode/Android Studio

Jetzt werden Änderungen an Ihrem Next.js code auf dem Gerät mit Hot-Reload aktualisiert.

Schritt 9: Erste mobile Bildschirmseite erstellen

Erstellen wir eine einfache, mobilen-freundliche Startseite. Aktualisieren src/app/page.tsx:

'use client';

import { useEffect, useState } from 'react';
import { App } from '@capacitor/app';
import { Keyboard } from '@capacitor/keyboard';

export default function Home() {
  const [appInfo, setAppInfo] = useState<{ name: string; version: string } | null>(null);

  useEffect(() => {
    // Get app info on mount
    App.getInfo().then(setAppInfo).catch(console.error);

    // Handle back button on Android
    const backHandler = App.addListener('backButton', ({ canGoBack }) => {
      if (!canGoBack) {
        App.exitApp();
      } else {
        window.history.back();
      }
    });

    // Hide keyboard when tapping outside inputs
    const keyboardHandler = Keyboard.addListener('keyboardWillShow', () => {
      document.body.classList.add('keyboard-open');
    });

    return () => {
      backHandler.then(h => h.remove());
      keyboardHandler.then(h => h.remove());
    };
  }, []);

  return (
    <main className="min-h-screen bg-linear-to-b from-blue-500 to-blue-700 flex flex-col items-center justify-center p-6 text-white">
      <h1 className="text-4xl font-bold mb-4">My Mobile App</h1>
      <p className="text-xl mb-8 text-center opacity-90">
        Built with Next.js 15 + Capacitor 8
      </p>

      {appInfo && (
        <div className="bg-white/20 rounded-lg p-4 backdrop-blur-sm">
          <p className="text-sm">
            {appInfo.name} v{appInfo.version}
          </p>
        </div>
      )}

      <div className="mt-12 space-y-4 w-full max-w-sm">
        <button className="w-full py-4 px-6 bg-white text-blue-600 rounded-xl font-semibold text-lg shadow-lg active:scale-95 transition-transform">
          Get Started
        </button>
        <button className="w-full py-4 px-6 bg-white/20 text-white rounded-xl font-semibold text-lg backdrop-blur-sm active:scale-95 transition-transform">
          Learn More
        </button>
      </div>
    </main>
  );
}

Schritt 10: Sicherheitsbereich verwalten

Smartphones haben Löcher, Heimindikatoren und Statusleisten. Fügen Sie den Sicherheitsbereich mit Tailwind hinzu.

Aktualisieren src/app/globals.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --sat: env(safe-area-inset-top);
  --sar: env(safe-area-inset-right);
  --sab: env(safe-area-inset-bottom);
  --sal: env(safe-area-inset-left);
}

body {
  padding-top: var(--sat);
  padding-right: var(--sar);
  padding-bottom: var(--sab);
  padding-left: var(--sal);
}

/* Prevent text selection on mobile */
* {
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* Allow text selection in inputs */
input, textarea {
  -webkit-user-select: auto;
  user-select: auto;
}

/* Keyboard handling */
.keyboard-open {
  --sab: 0px;
}

Projektstruktur

Ihr Projekt sollte jetzt wie folgt aussehen:

my-mobile-app/
├── android/              # Android native project
├── ios/                  # iOS native project
├── out/                  # Static build output
├── src/
│   ├── app/
│   │   ├── globals.css
│   │   ├── layout.tsx
│   │   └── page.tsx
│   └── ...
├── capacitor.config.ts   # Capacitor configuration
├── next.config.ts        # Next.js configuration
├── package.json
└── ...

Zukünftige Schritte

Sie haben jetzt eine funktionierende Next.js-Mobilanwendung. Hier sind die nächsten Schritte:

Wichtige Einstellungen

  • App-Ikone: Ersetzen Sie die Standardikonen in ios/App/App/Assets.xcassets und android/app/src/main/res
  • Splash-Screen: Anpassen in native Projekten oder verwenden Sie @capacitor/splash-screen config
  • Tiefe Links: Konfigurieren Sie die URL-Schemata für Ihre App

Hinzufügen von weiteren Funktionen

  • Kamera: bun add @capacitor/camera
  • Geolocation: bun add @capacitor/geolocation
  • Push Notifications: bun add @capacitor/push-notifications
  • Dateisystem: bun add @capacitor/filesystem

Natives UI und Übergänge

Verwenden Sie anstatt Konsta UI Capgo-Plugins für einen nativen mobilen Look:

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

Für Tailwind-Safe-Areas fügen Sie hinzu: @capgo/tailwind-capacitor:

bun add -D tailwind-capacitor

Siehe Mit @capgo/capacitor-native-Navigation, Mit @capgo/capacitor-Übergängen, und das tailwind-capacitor-Repository für die spezifische Einrichtung von Next.js.

iOS-Layoutprobleme beheben (Viewport, sichere Bereiche und horizontale Überschreitung)

Wenn Inhalte auf iOS gekürzt, verschoben oder horizontal scrollbar erscheinen, hilft das Hinzufügen oder Ändern des Viewport-Tags normalerweise nicht. Arbeiten Sie durch diese Kontrollen in der Reihenfolge. overflow-x: hidden Stellen Sie sicher, dass die Viewport-Metatag korrekt angewendet wird

App-Router

): export} (app/aus viewport __CAPGO_KEEP_0__ ist ein Platzhalter für Capacitor und __CAPGO_KEEP_1__ ist ein Platzhalter für native Navigation app/layout.tsx:

import type { Viewport } from 'next';

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

Seiten Router (pages/fügen Sie die Viewport-Meta-Tags ein pages/_app.tsxnicht _document.tsx.

Verwenden Sie den sicheren Bereich von iOS nur von einem Root-Wrapper aus

Erstellen Sie ein einzelnes App-Shell und fügen Sie dort den sicheren Bereich ein — nicht in mehreren verschachtelten Komponenten:

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);
}

Umgeben Sie alle Seiteninhalte mit .app-shellDoppelte sichere-Bereich-Paddings in Kopfzeilen, Modalen und Layout-Wrapper können die Benutzeroberfläche gekürzt oder zu groß aussehen lassen.

Mit @capgo/tailwind-capacitorkönnen Sie denselben Puffer mit Hilfsmitteln wie pt-safe pb-safe px-safe auf diesem einzelnen Shell ausdrücken.

Setzen Sie Capacitor iOS contentInset zu never erstes

In capacitor.config.ts, bevor Sie native Einstellungen deaktivieren und CSS (oder Native Navigation’s) contentInsetMode: 'css') die sichere Fläche übernehmen lässt:

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

Die Mischung aus Capacitor’s automatischer Inhaltseinstellung mit CSS-Paddings ist eine häufige Ursache für doppelte Zeilenabstände. env(safe-area-inset-*) Finden Sie das überlaufende Element

Der übliche Täter ist ein Element, das

, Tailwind 100vw, eine feste Pixelbreite oder eine große w-screenIn Safari Web Inspector, führen Sie: min-width.

In Safari Web Inspector, run:

[...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,
  }));

Mit Tailwind ersetzen Sie w-screen mit w-full Viele horizontalen Überschussprobleme rühren von 100vw / w-screen, dupliziertem sicheren Bereichsabstand oder einem festsitzenden Container — nicht von der Viewport-Meta-Tags selbst.

Over-the-Air-Updates

Einrichten Sie Capgo Um Updates ohne App-Store-Wiederabreitstellung zu pushen:

bunx @capgo/cli init

Fehlersuche

Builds scheitern mit „Cannot find module“ Laufen Sie bun install und probieren Sie es erneut.

iOS: "Kein Signierungsidentität gefunden" Öffnen Sie Xcode, gehen Sie zu Signing &amp; Fähigkeiten und wählen Sie Ihr Entwicklungsteam.

Android: "SDK-Ort nicht gefunden" Erstellen android/local.properties mit sdk.dir=/path/to/android/sdk

Änderungen erscheinen nicht auf dem Gerät Stellen Sie sicher, dass Sie "__CAPGO_KEEP_0__" nach der Änderung ausgeführt haben. Für Live-Neustart überprüfen Sie, ob die IP-Adresse korrekt ist und der Entwicklungs-Server läuft. bun run mobile Ressourcen

__CAPGO_KEEP_0__ 8 Dokumentation

Bereit, Ihre App zu verschicken? Lernen Sie, wie Capgo Ihnen dabei hilft, Updates schneller zu liefern — sich für ein kostenloses Konto anmelden heute.

Weitermachen von Build a Next.js Mobile App von Grund auf mit Capacitor 8

Wenn Sie Build a Next.js Mobile App von Grund auf mit Capacitor 8 zum Planen der CI/CD-Automatisierung verwenden, verbinden Sie es mit Capgo CI/CD für das Produktworkflow in Capgo CI/CD, Capgo Native Builds zur Produktworkflow in Capgo Native Builds Capgo Integrations zur Produktworkflow in Capgo Integrations CI/CD-Integration zur Implementierungsdetail in CI/CD-Integration, und GitHub Actions-Integration zur Implementierungsdetail in GitHub Actions-Integration

Live-Updates für Capacitor-Apps

Wenn ein Web-Schicht-Bug live ist, schicken Sie die Reparatur über Capgo anstatt Tage zu warten, bis die App-Store-Zulassung vorliegt. Die Benutzer erhalten die Aktualisierung im Hintergrund, während native Änderungen im normalen Review-Prozess bleiben.

Unterstützung von Martin

Loslegen

Neueste von unserem Blog

Capgo gibt Ihnen die besten Einblicke, die Sie benötigen, um eine wirklich professionelle mobile App zu erstellen.