Zum Hauptinhalt springen
Tutorial

Mobile Apps mit Vue und Capacitor bauen

Lerne, wie du eine mobile App mit Vue und Capacitor erstellst und optional Capgo Native Navigation, Transitions und iOS-Layout-Best-Practices optimierst.

Mobile Apps mit Vue und Capacitor bauen

In diesem Tutorial zeigen wir dir, wie du eine Vue-Web-App mit Capacitor in eine native Mobile App umwandelst. Du kannst zudem Capgo Native Navigation und Transitions für ein natives Feeling hinzufügen und tailwind-capacitor für Safe Areas nutzen.

Über Capacitor

Capacitor ist ein bahnbrechendes Tool, das sich einfach in jedes Web-Projekt integrieren lässt, um deine App in eine native Mobile App zu verwandeln. Es erstellt automatisch native Xcode- und Android Studio-Projekte und ermöglicht über eine JavaScript-Bridge den Zugriff auf native Device-Features wie die Kamera.

Deine Vue App vorbereiten

Erstelle zuerst eine neue Vue-App mit dem folgenden Befehl:

vue create my-app
cd my-app
npm install

Um deine Vue-App für das native Mobile Deployment vorzubereiten, musst du dein Projekt exportieren. Füge ein Script in deine package.json Datei ein, um das Vue-Projekt zu builden und zu kopieren:

{
  "scripts": {
    // ...
    "build": "vue-cli-service build"
  }
}

Nachdem du den build Befehl ausgeführt hast, solltest du einen neuen dist Ordner im Root-Verzeichnis deines Projekts sehen. Dieser Ordner wird später von Capacitor verwendet.

Capacitor zu deiner Vue-App hinzufügen

Um deine Vue-Web-App in einen nativen Mobile Container zu verwandeln, folge diesen Schritten:

  1. Installiere das Capacitor CLI als Dev-Dependency und richte es in deinem Projekt ein. Akzeptiere während des Setups die Standardwerte für Name und Bundle ID.

  2. Installiere das Core-Package sowie die relevanten Packages für iOS und Android.

  3. Füge die Plattformen hinzu, und Capacitor erstellt für jede Plattform einen Ordner im Root deines Projekts:

# Install the Capacitor CLI locally
npm install -D @capacitor/cli

# Initialize Capacitor in your Vue project
npx cap init

# Install the required packages
npm install @capacitor/core @capacitor/ios @capacitor/android

# Add the native platforms
npx cap add ios
npx cap add android

Du solltest jetzt neue iOS- und Android- Ordner in deinem Vue-Projekt sehen.

Aktualisiere die capacitor.config.json Datei nutzen, um das webDir auf das Ergebnis deines Build-Befehls zu setzen:

{
  "appId": "com.example.app",
  "appName": "my-app",
  "webDir": "dist"
}

Jetzt kannst du dein Vue-Projekt builden und mit Capacitor synchronisieren:

npm run build
npx cap sync

Native Apps bauen und deployen

Für die iOS-Entwicklung muss Xcode installiert sein, für Android-Apps benötigst du Android Studio. Zudem musst du dich im Apple Developer Program für iOS und in der Google Play Console für Android anmelden, um deine App in den App Stores zu veröffentlichen.

Nutze Capacitor CLI, um beide nativen Projekte zu öffnen:

npx cap open ios
npx cap open android

Deploye deine App auf ein verbundenes Gerät mit Android Studio oder Xcode.

Capacitor Live Reload

Aktiviere Live Reload auf deinem mobilen Gerät, indem die Capacitor App den Inhalt von einer spezifischen URL in deinem Netzwerk lädt.

Finde deine lokale IP-Adresse und aktualisiere die capacitor.config.ts Datei mit der korrekten IP und dem Port:

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

const config: CapacitorConfig = {
  appId: 'com.example.app',
  appName: 'my-app',
  webDir: 'dist',
  bundledWebRuntime: false,
  server: {
    url: 'http://192.168.x.xx:8080',
    cleartext: true
  }
};

export default config;

Wende diese Änderungen an, indem du sie in dein natives Projekt kopierst:

npx cap copy

Deine App wird nun automatisch neu geladen und Änderungen anzeigen, sobald du deine Vue-App aktualisierst.

Capacitor Plugins verwenden

Installiere ein Capacitor Plugin, wie zum Beispiel das Share-Plugin, und nutze es in deiner Vue-App:

npm i @capacitor/share

Importiere das Package und rufe die share() Funktion in deiner App:

<template>
  <div>
    <h1>Welcome to Vue and Capacitor!</h1>
    <button @click="share">Share now!</button>
  </div>
</template>

<script setup lang="ts">
import { Share } from '@capacitor/share';

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

Nach der Installation neuer Plugins führe den sync Befehl aus und redeploye die App auf dein Gerät:

npx cap sync

Anschließend kannst du die App auf iOS und Android mit Capgo Navigation und Übergängen nativ wirken lassen und gängige iOS-Layoutprobleme wie horizontalen Overflow oder abgeschnittene Safe Areas beheben.

Native-Feeling-UI mit Capgo Native Navigation und Transitions

Ich arbeite seit Jahren mit Ionic um plattformübergreifende Apps zu bauen, aber die Integration mit Vue ist oft umständlich und lohnt sich kaum, wenn man bereits Tailwind CSS.

Für ein natives Mobile-Feeling in einer Vue + Capacitor App solltest du Capgo Plugins statt reiner Web-UI-Kits wie Konsta UI nutzen:

  • @capgo/capacitor-native-navigation — native Navbar, Liquid Glass Tab Bar auf iOS und ein Blur-Effekt für die Tab Bar auf Android. Dein Vue Router verwaltet den Route-State; das Plugin übernimmt das native Chrome.
  • @capgo/capacitor-transitions — Page Transitions im Ionic-Stil und iOS Edge-Swipe-Back im WebView-Layer, ohne das Ionic UI zu übernehmen.

Beide installieren:

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

Konfiguriere die native Navigation mit dem CSS Inset Mode, damit der Web-Content die nativen Bars respektiert:

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

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

Rendere eine Liquid Glass Tab Bar (iOS nutzt systemeigenes Rendering; Android nutzt einen geblurrten WebView-Backdrop):

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

Füge native Page Transitions in deiner App-Shell hinzu:

<script setup>
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import '@capgo/capacitor-transitions';
import { initTransitions, setDirection, setupRouterOutlet } from '@capgo/capacitor-transitions/vue';

initTransitions({ platform: 'auto' });

const router = useRouter();
const outletRef = ref(null);

onMounted(() => {
  if (outletRef.value) {
    setupRouterOutlet(outletRef.value, { platform: 'auto', swipeGesture: 'auto' });
  }
});

const openSettings = () => {
  setDirection('forward');
  router.push('/settings');
};
</script>

<template>
  <cap-router-outlet ref="outletRef">
    <router-view />
  </cap-router-outlet>
</template>

Geroutete Pages wrappen in cap-router-outlet, cap-page, und cap-content, und aufrufen setDirection('forward') oder setDirection('back') vor der Navigation. Vermeide doppelte Web-Header oder -Footer, wenn die native Navigation diese Bereiche bereits übernimmt.

Hier findest du die vollständigen Guides: Verwendung von @capgo/capacitor-native-navigation und Verwendung von @capgo/capacitor-transitions.

Safe Areas mit Tailwind

Für Safe Areas auf Geräten in Tailwind CSS verwende @capgo/tailwind-capacitor (veröffentlicht als tailwind-capacitor auf npm). Es bietet safe-areas Utilities und weitere Capacitor-freundliche Tailwind-Plugins:

bun add -D tailwind-capacitor

Unter src/assets/main.css:

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

Nutze Utilities wie pt-safe, pb-safe, und px-safe anstatt sie überall env(safe-area-inset-*) manuell. Das Projekt wird aktiv weiterentwickelt – falls etwas für dein Vue-Setup fehlt, eröffne einen PR auf GitHub.

iOS-Layout-Probleme beheben (Viewport, Safe Area, Horizontal Overflow)

Falls Inhalte auf iOS abgeschnitten, verschoben oder horizontal scrollbar wirken, füge mehr overflow-x: hidden oder das bloße Anpassen des Viewport-Tags behebt das Problem meist nicht. Gehe diese Checks der Reihe nach durch.

Achte darauf, dass das Viewport-Meta-Tag korrekt gesetzt ist

Füge das Viewport-Meta-Tag in index.html innerhalb von <head>:

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />

iOS Safe Area nur über einen Root-Wrapper handhaben

Erstelle einen einzigen App-Shell und wende dort das Safe-Area-Padding an – nicht in mehreren verschachtelten Komponenten:

html,
body,
#app {
  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);
}

Umschließe den gesamten Seiteninhalt mit .app-shellDoppelte Safe-Area-Padding-Werte in Headern, Modals und Layout-Wrappern führen oft dazu, dass die UI abgeschnitten oder zu groß wirkt.

Mit @capgo/tailwind-capacitor, kannst du dasselbe Padding mit Utilities wie pt-safe pb-safe px-safe auf dieser einen Shell.

Setze Capacitor iOS contentInset zu never zuerst

Unter capacitor.config.ts, deaktiviere lieber native Insets und überlasse CSS (oder Native Navigation contentInsetMode: 'css') die Safe Area:

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

Das Mischen des automatischen Content Insets von Capacitor mit CSS env(safe-area-inset-*) Padding ist eine häufige Ursache für doppelte Abstände.

Das Element mit dem echten Overflow finden

Der übliche Übeltäter ist ein Element mit 100vw, Tailwind w-screen, einer festen Pixelbreite oder einem großen min-width.

Im Safari Web Inspector ausführen:

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

Ersetze bei Tailwind w-screen mit w-full wenn möglich. Viele horizontale Overflow-Probleme entstehen durch 100vw / w-screen, doppeltes Safe-Area-Padding oder einen Container mit fester Breite – nicht durch das Viewport-Meta-Tag selbst.

Fazit

Capacitor ist eine hervorragende Option, um native Apps auf Basis eines bestehenden Webprojekts zu erstellen. Mit Capgo lassen sich Live Updates noch einfacher in deine App integrieren, damit deine Nutzer immer Zugriff auf die neuesten Features und Bugfixes haben.

Erfahre, wie Capgo dir hilft, bessere Apps schneller zu bauen, melde dich für ein kostenloses Konto an – heute.

Weiterlesen: Mobile Apps mit Vue und Capacitor bauen

Wenn Sie ... verwenden Mobile Apps mit Vue und Capacitor bauen um natives Medien- und Interface-Verhalten zu planen, verbinde es mit @capgo/capacitor-live-activities verwenden für die native Funktion in „@capgo/capacitor-live-activities verwenden“, @capgo/capacitor-live-activities für das Implementierungsdetail in @capgo/capacitor-live-activities, @capgo/capacitor-video-player verwenden für die native Funktion in „@capgo/capacitor-video-player verwenden“, @capgo/capacitor-video-player für die Implementierungsdetails in @capgo/capacitor-video-player, und Verwendung von @capgo/capacitor-native-navigation für die native Funktionalität bei der Nutzung von @capgo/capacitor-native-navigation.

Live-Updates für Capacitor-Apps

Wenn ein Bug im Web-Layer live ist, rollst du den Fix über Capgo aus, statt Tage auf die App-Store-Freigabe zu warten. Nutzer bekommen das Update im Hintergrund, während native Änderungen weiter den normalen Review-Prozess durchlaufen.

Neuestes aus unserem Blog

Capgo bietet dir die besten Insights für eine wirklich professionelle Mobile App.