Einführung
Wollen Sie eine Nuxt-Mobilanwendung von Grund auf erstellen? Diese Anleitung führt Sie durch das Erstellen eines brandneuen Nuxt 4-Projekts, das von Anfang an für mobile Anwendungen konfiguriert ist, und das dann als native iOS- und Android-Anwendungen verpackt wird mit Capacitor 8.
Durch diese Anleitung erhalten Sie eine funktionierende Mobilanwendung, die auf Simulatoren läuft, die Sie weiterentwickeln und schließlich auf dem App Store und Google Play veröffentlichen können.
Zeitbedarf: ~30 Minuten
Was Sie bauen werden:
- Ein neues Nuxt 4-Projekt mit der neuesten Verzeichnisstruktur
- Konfiguration für statische Generierung für mobile Geräte
- Capacitor 8 mit wesentlichen Plugins
- NATIVE iOS- und Android-Apps
- Live-Reload-Entwicklungsumgebung
Haben Sie bereits eine Nuxt-App? Überprüfen Sie stattdessen Ihre Nuxt-App auf mobile umwandeln Voraussetzungen
Voraussetzungen
Stellen Sie sicher, dass Sie diese installiert haben:
- Node.js 18+ (überprüfen Sie mit
node --version) - Bun Paketmanager (
curl -fsSL https://bun.sh/install | bash) - Xcode (nur für macOS, für iOS-Entwicklung)
- Android Studio (für Android-Entwicklung)
Schritt 1: Erstellen Sie ein neues Nuxt 4-Projekt
Beginnen Sie mit der Erstellung eines frischen Nuxt 4-Projekts:
bunx nuxi@latest init my-mobile-app
cd my-mobile-app
bun install
Nuxt 4-Verzeichnisstruktur
Nuxt 4 verwendet eine neue Verzeichnisstruktur mit app code im app/ Verzeichnis:
my-mobile-app/
app/
assets/
components/
composables/
layouts/
middleware/
pages/
plugins/
utils/
app.vue
public/
server/
nuxt.config.ts
package.json
Dieses Layout bietet eine bessere Trennung zwischen App und Server code.
Schritt 2: Konfigurieren Sie Nuxt für statische Generierung
Capacitor erfordert statische HTML/JS/CSS-Dateien. Konfigurieren Sie Nuxt für statische Generierung in nuxt.config.ts:
export default defineNuxtConfig({
compatibilityDate: '2025-01-15',
devtools: { enabled: true },
// Enable static generation
ssr: true,
nitro: {
preset: 'static',
},
});
Schritt 3: Hinzufügen von mobilen Skripten
Aktualisieren Sie Ihre package.json mit mobilen Entwicklungs-Skripten:
{
"scripts": {
"dev": "nuxt dev",
"build": "nuxt build",
"generate": "nuxt generate",
"preview": "nuxt preview",
"mobile": "bun run generate && bunx cap sync",
"mobile:ios": "bun run mobile && bunx cap open ios",
"mobile:android": "bun run mobile && bunx cap open android"
}
}
Testen Sie die statische Generierung:
bun run generate
Sie sollten ein .output/public Verzeichnis mit Ihren statischen Dateien sehen.
Schritt 4: Installieren Sie Capacitor 8
Installieren Sie die Capacitor-Kernpakete:
bun add @capacitor/core
bun add -D @capacitor/cli
Installieren Sie wichtige Plugins, die die meisten mobilen Apps benötigen:
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/status-bar @capacitor/preferences
Was diese Plugins tun:
- @capacitor/app — Ereignisse im App-Lebenszyklus (Vordergrund/Hintergrund, tiefere Links)
- — @capacitor/keyboard — Tastaturverhalten steuern
- — @capacitor/splash-screen — Kontrolle der nativen Splash-Screen
- — @capacitor/status-bar — Gestalten Sie die Geräte-Statusleiste
- — @capacitor/preferences — Schlüssel-Wert-Speicher (wie localStorage, aber native)
Schritt 5: Initialisiere Capacitor
Initialisiere Capacitor mit Ihren Projekt-Daten:
bunx cap init "My Mobile App" com.example.mymobileapp --web-dir .output/public
Ersetzen Sie:
"My Mobile App"mit dem Namen Ihres Anwendungs-Displayscom.example.mymobileappmit Ihrer App-ID (umgekehrte Domänennotation)
Dies erstellt capacitor.config.ts. Aktualisieren Sie es mit der Plugin-Konfiguration:
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.mymobileapp',
appName: 'My Mobile App',
webDir: '.output/public',
plugins: {
SplashScreen: {
launchShowDuration: 2000,
launchAutoHide: true,
androidScaleType: 'CENTER_CROP',
splashFullScreen: true,
splashImmersive: true,
},
Keyboard: {
resize: 'body',
resizeOnFullScreen: true,
},
StatusBar: {
style: 'dark',
},
},
};
export default config;
Schritt 6: Fügen Sie native Plattformen hinzu
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 mit den native Projekten.
Schritt 7: Erstellen und Ausführen
Erstellen 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):
- Wählen Sie einen Simulator aus dem Geräte-Auswahlfeld
- Klicken Sie auf die Play-Taste oder drücken Sie
Cmd + R
In Android Studio:
- Warten Sie, bis Gradle fertig ist, die Synchronisierung zu beenden
- Wählen Sie einen Emulator aus dem Geräte-Auswahlfeld
- Klicken Sie auf die Ausführungs-Schaltfläche oder drücken Sie
Shift + F10
Schritt 8: Einrichten von Live Reload
Für eine schnellere Entwicklung aktivieren Sie Live Reload, damit Änderungen sofort auf Ihrem Gerät erscheinen.
- Finden Sie Ihre lokale IP-Adresse:
# macOS
ipconfig getifaddr en0
# Windows
ipconfig
- Create a development Capacitor config. Update
capacitor.config.ts:
import type { CapacitorConfig } from '@capacitor/cli';
const devConfig: CapacitorConfig = {
appId: 'com.example.mymobileapp',
appName: 'My Mobile App',
webDir: '.output/public',
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: '.output/public',
plugins: {
// ... same plugin config
},
};
const config = process.env.NODE_ENV === 'development' ? devConfig : prodConfig;
export default config;
- Starten Sie den Entwicklungs-Server und kopieren Sie die Konfiguration in die native Umgebung:
bun run dev &
NODE_ENV=development bunx cap copy
- Rebuild in Xcode/Android Studio
Now edits to your Nuxt code will hot-reload on the device.
Schritt 9: Erstellen Sie Ihre erste mobile Bildschirm
Erstellen Sie einen mobilen-freundlichen Home-Screen. Aktualisieren Sie app/app.vue:
<template>
<NuxtPage />
</template>
Erstellen Sie app/pages/index.vue:
<template>
<main
class="min-h-screen bg-linear-to-b from-green-500 to-green-700 flex flex-col items-center justify-center p-6 text-white"
>
<h1 class="text-4xl font-bold mb-4">My Mobile App</h1>
<p class="text-xl mb-8 text-center opacity-90">
Built with Nuxt 4 + Capacitor 8
</p>
<div v-if="appInfo" class="bg-white/20 rounded-lg p-4 backdrop-blur-sm mb-8">
<p class="text-sm">
{{ appInfo.name }} v{{ appInfo.version }}
</p>
</div>
<div class="space-y-4 w-full max-w-sm">
<button
class="w-full py-4 px-6 bg-white text-green-600 rounded-xl font-semibold text-lg shadow-lg active:scale-95 transition-transform"
@click="handleGetStarted"
>
Get Started
</button>
<button
class="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"
@click="handleShare"
>
Share App
</button>
</div>
</main>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { App } from '@capacitor/app';
const appInfo = ref<{ name: string; version: string } | null>(null);
let backButtonListener: { remove: () => void } | null = null;
onMounted(async () => {
// Get app info
try {
appInfo.value = await App.getInfo();
} catch (e) {
// Web fallback
appInfo.value = { name: 'My Mobile App', version: '1.0.0' };
}
// Handle Android back button
backButtonListener = await App.addListener('backButton', ({ canGoBack }) => {
if (!canGoBack) {
App.exitApp();
} else {
window.history.back();
}
});
});
onUnmounted(() => {
backButtonListener?.remove();
});
function handleGetStarted() {
// Navigate to onboarding or main app
console.log('Get started clicked');
}
async function handleShare() {
// We'll implement this with the Share plugin later
console.log('Share clicked');
}
</script>
Schritt 10: Hinzufügen von Tailwind CSS
Nun fügen Sie Tailwind CSS Ihrem Projekt hinzu:
bun add tailwindcss @tailwindcss/vite
aktualisieren nuxt.config.ts:
import tailwindcss from '@tailwindcss/vite';
export default defineNuxtConfig({
compatibilityDate: '2025-01-15',
devtools: { enabled: true },
ssr: true,
nitro: {
preset: 'static',
},
css: ['~/assets/css/main.css'],
vite: {
plugins: [tailwindcss()],
},
});
erstellen app/assets/css/main.css:
@import 'tailwindcss';
: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;
}
Schritt 11: Fügen Sie den Teilen-Plugin hinzu
Implementieren wir nun die Funktion für die Teilen-Schaltfläche:
bun add @capacitor/share
um das Teilen-Plugin zu verwenden: app/pages/index.vue Überprüfen und neu erstellen:
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { App } from '@capacitor/app';
import { Share } from '@capacitor/share';
// ... existing code ...
async function handleShare() {
try {
await Share.share({
title: 'Check out this app!',
text: 'Built with Nuxt 4 and Capacitor 8',
url: 'https://capacitorjs.com',
dialogTitle: 'Share with friends',
});
} catch (e) {
console.log('Share cancelled or failed:', e);
}
}
</script>
Projektstruktur
bun run mobile
Ihr Projekt sollte nun wie folgt aussehen:
Zukünftige Schritte
my-mobile-app/
├── android/ # Android native project
├── ios/ # iOS native project
├── .output/
│ └── public/ # Static build output
├── app/
│ ├── assets/
│ │ └── css/
│ │ └── main.css
│ ├── pages/
│ │ └── index.vue
│ └── app.vue
├── capacitor.config.ts # Capacitor configuration
├── nuxt.config.ts # Nuxt configuration
├── package.json
└── ...
context: Capgo Builder / native cloud build product page. Role: Short UI label or navigation item. Message key `native_build_builder_credit_next` (Native Build Builder Credit Next).
Ihr Nuxt-Mobilanwendung funktioniert jetzt. Hier sind die nächsten Schritte:
Grundlegende Einstellungen
- App-Icons: Ersetzen Sie die Standardicons in
ios/App/App/Assets.xcassetsundandroid/app/src/main/res - Splash Screen: Anpassen in native Projekten oder verwenden Sie
@capacitor/splash-screenconfig - Deep Links: Konfigurieren Sie die URL-Schemas für Ihre App
Hinzufügen Sie weitere Funktionen
- Kamera:
bun add @capacitor/camera - Geolocation:
bun add @capacitor/geolocation - Benachrichtigungen:
bun add @capacitor/push-notificationsoder @capgo/capacitor-firebase-messaging Wenn Sie Firebase Cloud Messaging auf iOS und Android verwenden möchten - Dateisystem:
bun add @capacitor/filesystem
Native Benutzeroberfläche und Übergänge
Verwenden Sie stattdessen Capgo-Plugins, um eine nativ anfühlsame mobile App zu erstellen:
- @capgo/capacitor-native-navigation — Liquid Glass-Tastenleiste und nativer Navbar
- @capgo/capacitor-transitions — nativ anfühlsame Seitenübergänge
bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync
Um Tailwind-Safe-Areas hinzuzufügen @capgo/tailwind-capacitor:
bun add -D tailwind-capacitor
Siehe Verwenden Sie @capgo/capacitor-native-Navigation, Verwenden Sie @capgo/capacitor-Übergänge, und das tailwind-capacitor-Repository zur Nuxt-spezifischen Einrichtung.
Fixierung von iOS-Anordnungsproblemen (Viewport, sichere Fläche und horizontale Überlauf)
Wenn Inhalte auf iOS gekürzt, verschoben oder horizontal scrollbar aussehen, fügt oder passt die Anpassung der Viewport-Tags allein normalerweise nicht aus. Arbeiten Sie durch diese Kontrollen in der Reihenfolge. overflow-x: hidden Stellen Sie sicher, dass der Viewport-Meta-Tag korrekt angewendet wird
In
Stellen Sie sicher, dass der Viewport-Meta-Tag korrekt angewendet wird nuxt.config.tsSetze die Ansicht durch app.head:
export default defineNuxtConfig({
app: {
head: {
meta: [
{
name: 'viewport',
content: 'width=device-width, initial-scale=1, viewport-fit=cover',
},
],
},
},
});
Behandle die iOS-Sicherheitszone von einem einzigen Root-Wrapper aus
Erstelle eine einzelne App-Shell und füge dort Sicherheitsbereich-Puffer an — nicht in mehreren verschachtelten Komponenten:
html,
body,
#__nuxt {
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);
}
Umfasst alle Seite-Inhalte innerhalb von .app-shell. Doppelte Sicherheitsbereich-Puffer in Kopfzeilen, Modalen und Layout-Wrapper machen die Benutzeroberfläche oft gekürzt oder zu groß aus.
Mit @capgo/tailwind-capacitorKannst du denselben Puffer mit Hilfsmitteln wie pt-safe pb-safe px-safe auf dieser einzelnen Schale ausdrücken.
Setze Capacitor iOS contentInset auf never context: Seite/Bereich: Produktseite mit Live-Updates. Rolle: Kurzer Benutzeroberflächentitel oder Navigationselement. Nachrichtenschlüssel `live_update_dynamic_label_to` (Live Update Dynamic Label To).
In capacitor.config.ts, bevorzugt native Eingriff deaktiviert und lasse CSS (oder Native Navigation’s) contentInsetMode: 'css') den sicheren Bereich besitzen:
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: '.output/public',
ios: {
contentInset: 'never',
},
};
Mischen Sie Capacitor’s automatische Inhalts-Einrastung mit CSS env(safe-area-inset-*) Padding ist eine häufige Ursache für doppelte Abstände.
Finden Sie das überlaufende Element
Der übliche Täter ist ein Element, das 100vw, Tailwind w-screen, eine feste Pixelbreite oder eine große min-width.
In Safari Web Inspector, ausführen Sie:
[...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 durch w-full Wenn möglich. Viele horizontale Überschreitung von Problemen kommen von 100vw / w-screendoppeltem sicheren Bereich-Puffer oder einem festsitzenden Container — nicht von der Meta-Tags für die Ansicht selbst.
Über-Air-Updates
Einstellungen Capgo zum Pushen von Updates ohne App-Store-Neuabgabe:
bunx @capgo/cli init
Hilfe bei Problemen
Builds scheitern mit „Cannot find module“
Ausführen bun install und probieren Sie es erneut.
iOS: „Kein Signierungsidentität gefunden“ Öffnen Sie Xcode, gehen Sie zu Signieren und Fähigkeiten und wählen Sie Ihr Entwicklerteam.
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 bun run mobile nachdem Sie Änderungen vorgenommen haben. Für Live-Reload überprüfen Sie, ob die IP-Adresse korrekt ist und der Entwicklungs-Server läuft.
.output/public ist leer oder fehlt
Stellen Sie sicher, dass Sie nitro: { preset: 'static' } in nuxt.config.ts und ausführen bun run generate.
Ressourcen
- Capacitor 8 Dokumentation
- Nuxt 4 Dokumentation
- Capgo - Live Updates
- @capgo/capacitor-native-Navigation
- @capgo/capacitor-Übergänge
- @capgo/tailwind-capacitor
Ihre App bereitstellen? Erfahren Sie, wie Capgo Ihnen dabei hilft, Updates schneller zu liefern — jetzt kostenlos anmelden Fortsetzen von Build a Nuxt Mobile App von Grund auf mit __CAPGO_KEEP_0__ 8
Keep going from Build a Nuxt Mobile App from Scratch with Capacitor 8
Build a Nuxt Mobile App von Grund auf mit __CAPGO_KEEP_0__ 8 Build a Nuxt Mobile App from Scratch with Capacitor 8 Keep going from Build a Nuxt Mobile App from Scratch with __CAPGO_KEEP_0__ 8 Capgo CI/CD zur 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