Saltar al contenido principal
Guía del tutor

Crear una aplicación móvil de Nuxt desde cero con Capacitor 8

Guía paso a paso para crear un nuevo proyecto de Nuxt 4 y convertirlo en aplicaciones móviles nativas de iOS y Android utilizando Capacitor 8. Ideal para empezar de cero con el desarrollo de Vue móvil.

Martin Donadieu

Martin Donadieu

Gerente de contenido

Crear una aplicación móvil de Nuxt desde cero con Capacitor 8

Introducción

¿Quieres crear una aplicación móvil con Nuxt desde cero? Esta guía te guía a través de la creación de un proyecto de Nuxt 4 configurado para móvil desde el principio, luego empaquetarlo como aplicaciones móviles nativas de iOS y Android utilizando Capacitor 8.

Al final de esta guía, tendrás una aplicación móvil en funcionamiento que corre en simuladores que puedes seguir desarrollando y eventualmente publicar en la Tienda de App y Google Play.

Tiempo requerido: ~30 minutos

¿Qué construirás:

  • Un nuevo proyecto de Nuxt 4 con la estructura de directorios más reciente
  • Configuración de generación estática para móviles
  • Capacitor 8 con plugins esenciales
  • Aplicaciones nativas de iOS y Android
  • Configuración de desarrollo con recarga en vivo

Ya tienes una aplicación de Nuxt? Consulta Convierte tu aplicación de Nuxt a móvil en su lugar.

Requisitos previos

Asegúrese de tener instalados los siguientes:

  • Node.js 18+ (verifique con node --version)
  • Bun administrador de paquetes (curl -fsSL https://bun.sh/install | bash)
  • Xcode (solo para macOS, para desarrollo de iOS)
  • Android Studio (para desarrollo de Android)

Paso 1: Crear un Nuevo Proyecto de Nuxt 4

Comience creando un proyecto de Nuxt 4 fresco:

bunx nuxi@latest init my-mobile-app
cd my-mobile-app
bun install

Estructura de Directorio de Nuxt 4

Nuxt 4 utiliza una nueva estructura de directorio con app code en el app/ directorios:

my-mobile-app/
  app/
    assets/
    components/
    composables/
    layouts/
    middleware/
    pages/
    plugins/
    utils/
    app.vue
  public/
  server/
  nuxt.config.ts
  package.json

Esta estructura proporciona una mejor separación entre la aplicación y el servidor code.

Paso 2: Configurar Nuxt para la Generación Estática

Capacitor requiere archivos HTML/JS/CSS estáticos. Configura Nuxt para la generación estática en nuxt.config.ts:

export default defineNuxtConfig({
  compatibilityDate: '2025-01-15',
  devtools: { enabled: true },

  // Enable static generation
  ssr: true,
  nitro: {
    preset: 'static',
  },
});

Paso 3: Agregar Scripts Móviles

Actualiza tu package.json con scripts de desarrollo móvil:

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

Prueba la generación estática:

bun run generate

Deberías ver un .output/public directorios con tus archivos estáticos.

Paso 4: Instalar Capacitor 8

Instale los paquetes de núcleo Capacitor:

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

Instale los plugins esenciales que la mayoría de las aplicaciones móviles necesitan:

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

¿Qué hacen estos plugins:

  • @capacitor/app — Eventos de ciclo de vida de la aplicación (anterior/plano, enlaces profundos)
  • @capacitor/keyboard — Control del comportamiento del teclado
  • @capacitor/splash-screen — Control de pantalla de bienvenida nativa
  • @capacitor/status-bar — Estile el barra de estado del dispositivo
  • @capacitor/preferences — Almacenamiento de valores clave (como localStorage pero nativo)

Paso 5: Inicializa Capacitor

Inicializa Capacitor con los detalles de tu proyecto:

bunx cap init "My Mobile App" com.example.mymobileapp --web-dir .output/public

Reemplaza:

  • "My Mobile App" con el nombre de pantalla de tu aplicación
  • com.example.mymobileapp con el ID de tu aplicación (notación de dominio inverso)

Esto crea capacitor.config.ts. Actualiza con la configuración del plugin:

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;

Paso 6: Agrega Plataformas Nativas

Instala los paquetes de plataforma:

bun add @capacitor/ios @capacitor/android

Genera los proyectos nativos:

bunx cap add ios
bunx cap add android

Esto crea ios y los directorios que contienen los proyectos nativos. android Paso 7: Construye y Ejecuta

Construye tu proyecto y sincroniza con las plataformas nativas:

Abrir en iOS Simulator:

bun run mobile

O Android Emulator:

bun run mobile:ios

En Xcode (iOS):

bun run mobile:android

Selecciona un simulador desde el menú de dispositivos

  1. Haz clic en el botón de reproducción o presiona
  2. En Android Studio: Cmd + R

Espera a que Gradle termine de sincronizar

  1. Selecciona un emulador desde el menú de dispositivos
  2. Step 7: Build and Run
  3. Haga clic en el botón Ejecutar o presione Shift + F10

Paso 8: Configura Live Reload

Para un desarrollo más rápido, habilite el live reload para que los cambios aparezcan instantáneamente en su dispositivo.

  1. Encuentre su dirección IP local:
# macOS
ipconfig getifaddr en0

# Windows
ipconfig
  1. Cree un archivo de configuración de desarrollo Capacitor. Actualice 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;
  1. Inicie el servidor de desarrollo y copie la configuración a nativo:
bun run dev &
NODE_ENV=development bunx cap copy
  1. Reconstruya en Xcode/Android Studio

Ahora los cambios en su Nuxt code se recargarán automáticamente en el dispositivo.

Paso 9: Crea la primera pantalla móvil

Vamos a crear una pantalla de inicio amigable con dispositivos móviles. Actualice app/app.vue:

<template>
  <NuxtPage />
</template>

Crear 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>

Paso 10: Agregue Tailwind CSS

Para que el estilo funcione, agregue Tailwind CSS a su proyecto:

bun add tailwindcss @tailwindcss/vite

Actualizar 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()],
  },
});

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

Paso 11: Agregue el plugin de Compartir

Vamos a implementar la funcionalidad del botón de compartir:

bun add @capacitor/share

Actualizar app/pages/index.vue para utilizar el plugin de Compartir:

<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>

Sincronice y reconstruya:

bun run mobile

Estructura del Proyecto

Su proyecto debería verse ahora así:

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
└── ...

Pasos siguientes

Ahora tiene una aplicación móvil de Nuxt funcionando. Aquí está qué hacer a continuación:

Configuración Básica

  • Íconos de la Aplicación: Reemplaza los íconos predeterminados en ios/App/App/Assets.xcassets y android/app/src/main/res
  • Pantalla de Inicio: Personaliza en proyectos nativos o utiliza @capacitor/splash-screen config
  • Enlaces Profundos: Configura esquemas de URL para tu aplicación

Agregar Más Funcionalidades

  • Cámara: bun add @capacitor/camera
  • Ubicación: bun add @capacitor/geolocation
  • Notificaciones de Push: bun add @capacitor/push-notifications
  • Sistema de Archivos: bun add @capacitor/filesystem

Mejora de IU

Considerar agregar Konsta UI para componentes iOS/Android que parezcan nativos:

bun add konsta

Luego actualice su CSS para importar el tema:

@import 'tailwindcss';
@import 'konsta/theme.css';

Actualizaciones en Línea

Configuración Capgo para enviar actualizaciones sin la necesidad de volver a subir la aplicación a la tienda:

bunx @capgo/cli init

Solución de Problemas

Fallan los compilaciones con “No se puede encontrar el módulo” Ejecutar bun install y vuelve a intentarlo.

iOS: “No se encontró la identidad de firma” Abre Xcode, ve a Signing & Capabilities, y selecciona tu equipo de desarrollo.

Android: “SDK no se encontró en la ubicación” Crear android/local.properties con sdk.dir=/path/to/android/sdk

Los cambios no se muestran en el dispositivo Asegúrate de que hayas ejecutado bun run mobile después de hacer cambios. Para el recarga en vivo, verifica que la dirección IP sea correcta y que el servidor de desarrollo esté en ejecución.

.output/public está vacío o faltante Asegúrese de que ha configurado nitro: { preset: 'static' } en nuxt.config.ts y ejecutar bun run generate.

Recursos

¿Listo para enviar su aplicación? Aprenda cómo Capgo puede ayudarlo a entregar actualizaciones más rápido — suscribirse a una cuenta gratuita hoy.

Actualizaciones en vivo para aplicaciones Capacitor

Cuando haya un error en la capa web, envíe la corrección a través de Capgo en lugar de esperar días a la aprobación de la tienda de aplicaciones. Los usuarios obtienen la actualización en segundo plano mientras que los cambios nativos siguen en el camino de revisión normal.

Comience Ahora

Últimas noticias de nuestro Blog

Capgo le da las mejores pistas que necesita para crear una aplicación móvil verdaderamente profesional.