Saltar al contenido principal
Tutorial

Convierte tu app de Next.js a iOS y Android con Capacitor 8

Convierte tu aplicación web de Next.js 15 en apps nativas para iOS y Android con Capacitor. Una guía completa para configurar el static export, añadir plugins nativos y desplegar en las app stores.

Convierte tu app de Next.js a iOS y Android con Capacitor 8

Introducción

¿Tienes una web app en Next.js? En esta guía aprenderás a convertirla en apps nativas para iOS y Android usando Capacitor 8 — la última versión con mejor rendimiento y nuevas funciones.

Capacitor envuelve tu web app en un contenedor nativo, dándote acceso a APIs del dispositivo como cámara, filesystem y push notifications sin cambiar tu codebase de React. A diferencia de React Native, no tienes que reescribir nada: tu code de Next.js funciona tal cual.

Lo que aprenderás:

  • Configurar tu app Next.js actual para exportación estática
  • Añadir Capacitor 8 con plugins nativos esenciales
  • Build y testing en simuladores de iOS y Android
  • Habilitar live reload para un desarrollo más rápido
  • Solucionar problemas comunes de layout en iOS (viewport, safe area, horizontal overflow)
  • Añadir una UI con feeling nativo con Capgo Native Navigation and Transitions

¿Quieres empezar un proyecto desde cero? Mira nuestra guía sobre Cómo crear una app móvil con Next.js desde cero.

Beneficios de usar Next.js y Capacitor

  • Reusabilidad de Code: Next.js te permite escribir componentes reutilizables y compartir code entre tus apps web y móviles, ahorrando tiempo y esfuerzo de desarrollo.
  • Rendimiento: Next.js ofrece optimizaciones de rendimiento integradas, como server-side rendering y code splitting, garantizando tiempos de carga rápidos y una experiencia fluida.
  • Capacidades nativas: Capacitor brinda acceso a funciones nativas del dispositivo como la cámara, geolocalización y más, permitiéndote crear apps móviles muy completas.
  • Desarrollo simplificado: Con Capacitor, puedes desarrollar y probar tu app móvil usando tecnologías web familiares, reduciendo la curva de aprendizaje y agilizando el proceso.

Requisitos

Antes de empezar, asegúrate de tener:

  • Node.js 18+ instalado
  • Un Next.js 15+ aplicación
  • Xcode (para desarrollo iOS, solo macOS)
  • Android Studio (para desarrollo Android)

Configurar tu app de Next.js para móvil

El primer paso es configurar tu app de Next.js para exportación estática. Capacitor necesita archivos HTML/JS/CSS estáticos para crear el bundle de la app nativa.

Abre tu next.config.js (o next.config.ts) archivo y añade la configuración de exportación:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: {
    unoptimized: true,
  },
};

module.exports = nextConfig;

El output: 'export' esta configuración le indica a Next.js que genere archivos HTML estáticos, y images: { unoptimized: true } evita la optimización de imágenes de Next.js, que requiere un servidor.

Importante: Si usas funciones que requieren un servidor (API routes, server components con data fetching, etc.), tendrás que refactorizarlas para usar alternativas en el cliente o APIs externas.

Añade scripts específicos para móviles a tu package.json:

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

Prueba la exportación estática ejecutando:

bun run build

Deberías ver una carpeta out en la raíz de tu proyecto. Aquí están todos los archivos estáticos que Capacitor incluirá en tu app nativa.

Añadir Capacitor 8 a tu proyecto

Para empaquetar tu app de Next.js en un contenedor móvil nativo, sigue estos pasos:

  1. Instala el core de Capacitor y CLI:
bun add @capacitor/core
bun add -D @capacitor/cli
  1. Instala los plugins de Capacitor más comunes que probablemente necesites:
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/preferences

Estos plugins ofrecen funciones esenciales:

  • @capacitor/app: Gestionar eventos del ciclo de vida (foreground/background, URLs)
  • @capacitor/keyboard: Controlar el comportamiento del teclado en móviles
  • @capacitor/splash-screen: Gestionar la splash screen nativa
  • @capacitor/preferences: Almacenar datos clave-valor de forma persistente
  1. Inicializa Capacitor con los detalles de tu proyecto:
bunx cap init my-app com.example.myapp --web-dir out

Reemplaza my-app con el nombre de tu app y com.example.myapp con el ID de tu app (notación de dominio inverso).

  1. Crea o actualiza el capacitor.config.ts archivo con la configuración adecuada:
import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.myapp',
  appName: 'my-app',
  webDir: 'out',
  plugins: {
    SplashScreen: {
      launchShowDuration: 2000,
      launchAutoHide: true,
      androidScaleType: 'CENTER_CROP',
      showSpinner: false,
      splashFullScreen: true,
      splashImmersive: true,
    },
  },
};

export default config;
  1. Instala las plataformas nativas:
bun add @capacitor/ios @capacitor/android
  1. Añade las carpetas de las plataformas nativas:
bunx cap add ios
bunx cap add android

Capacitor creará ios y android carpetas en la raíz de tu proyecto con los proyectos nativos.

Para buildear el proyecto de Android, necesitas Android Studio. Para iOS, necesitas un Mac con Xcode.

  1. Haz el build y sincroniza tu proyecto:
bun run mobile

Esto ejecuta tu script personalizado que hace el build del proyecto Next.js y sincroniza los archivos estáticos con las plataformas nativas.

Build y despliegue de apps nativas

Para hacer el build y desplegar tu app móvil nativa, sigue estos pasos: Para desarrollar apps de iOS, necesitas tener Xcode instalado, y para apps de Android, necesitas tener Android Studio instalado. Además, si planeas distribuir tu app en la tienda de apps, debes inscribirte en el Apple Developer Program para iOS y en Google Play Console para Android.

  1. Abre los proyectos nativos:

Para iOS:

bun run mobile:ios

Para Android:

bun run mobile:android

O directamente con Capacitor CLI:

bunx cap open ios
bunx cap open android
  1. Compila y ejecuta la app:

android-studio-run

  • En Android Studio, espera a que el proyecto esté listo y haz clic en el botón “Run” para desplegar la app en un dispositivo conectado o emulador. xcode-run

  • En Xcode, configura tu cuenta de firma para desplegar la app en un dispositivo real. Si no lo has hecho antes, Xcode te guiará en el proceso (ten en cuenta que debes estar inscrito en el Apple Developer Program). Una vez configurado, haz clic en el botón “Play” para ejecutar la app en tu dispositivo conectado.

¡Felicidades! Has desplegado con éxito tu web app de Next.js en un dispositivo móvil.

nextjs-mobile-app
Pero espera, también hay una forma más rápida de hacerlo durante el desarrollo...

Live Reload con Capacitor

Durante el desarrollo, puedes aprovechar el live reloading para ver los cambios al instante en tu móvil. Para activar esta función, sigue estos pasos:

  1. Busca tu dirección IP local:
  • En macOS, ejecuta el siguiente comando en la terminal:

    ipconfig getifaddr en0
  • En Windows, ejecuta:

    ipconfig

    Busca la dirección IPv4 en la salida.

  1. Actualiza tu capacitor.config.ts para apuntar a tu servidor de desarrollo:
import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.app',
  appName: 'my-app',
  webDir: 'out',
  server: {
    url: 'http://YOUR_IP_ADDRESS:3000',
    cleartext: true,
  },
};

export default config;

Reemplaza YOUR_IP_ADDRESS con tu dirección IP local (ej. 192.168.1.100).

  1. Aplica los cambios a tu proyecto nativo:
bunx cap copy

El copy el comando copia la carpeta web y los cambios de configuración al proyecto nativo sin actualizar todo el proyecto.

  1. Reconstruye y ejecuta la app en tu dispositivo usando Android Studio o Xcode.

Ahora, cada vez que hagas cambios en tu app de Next.js, la app móvil se recargará automáticamente para reflejarlos.

Nota: Si instalas nuevos plugins o modificas archivos nativos, tendrás que reconstruir el proyecto nativo, ya que el live reloading solo aplica a cambios en la web code.

Uso de plugins de Capacitor

Los plugins de Capacitor te permiten acceder a funciones nativas del dispositivo desde tu app de Next.js. Veamos cómo usar el Plugin de compartir como ejemplo:

  1. Instala el plugin Share:
bun add @capacitor/share
  1. Actualiza el pages/index.js archivo para usar el plugin Share:
import Head from 'next/head';
import styles from '../styles/Home.module.css';
import { Share } from '@capacitor/share';

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

  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>
          Welcome to <a href="https://nextjs.org">Capgo!</a>
        </h1>

        <p className={styles.description}>
          <h2>Cool channel</h2>
          <button onClick={() => share()}>Share now!</button>
        </p>
      </main>
    </div>
  );
}
  1. Sincroniza los cambios con el proyecto nativo:

Como mencionamos antes, al instalar nuevos plugins, debemos hacer un sync y luego volver a desplegar la app en nuestro dispositivo. Para ello, ejecuta el siguiente comando:

bun run mobile

O simplemente sincroniza sin reconstruir:

bunx cap sync
  1. Reconstruye y ejecuta la app en tu dispositivo.

Ahora, al pulsar el botón “Share now!”, aparecerá el diálogo nativo de compartir, permitiéndote enviar el contenido a otras apps.

next-capacitor-share
A continuación, puedes hacer que la app se sienta más nativa en iOS y Android con la navegación y las transiciones de Capgo, y corregir problemas comunes de layout en iOS que provocan desbordamiento horizontal o safe areas recortadas. ## Una UI que se siente nativa con Capgo Native Navigation and Transitions

He trabajado durante años con Ionic para crear aplicaciones multiplataforma, pero integrarlo con Next.js es hacky y rara vez vale la pena cuando ya tienes Tailwind CSS 4.

Para lograr una sensación nativa en una app de Next.js + Capacitor, usa plugins de Capgo en lugar de UI kits solo web como Konsta UI:

  • @capgo/capacitor-native-navigation — navbar nativa, Liquid Glass tab bar en iOS y un estilo de tab bar con desenfoque en Android. Tu router de Next.js mantiene el estado de la ruta; el plugin se encarga del chrome nativo.
  • @capgo/capacitor-transitions — Transiciones de página estilo Ionic y gesto de retroceso en iOS en la capa WebView, sin necesidad de usar Ionic UI.

Instala ambos:

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

Configura la navegación nativa con CSS inset mode para que el contenido web respete las barras nativas:

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

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

Renderiza una tab bar Liquid Glass (iOS usa renderizado del sistema; Android usa un fondo WebView desenfocado):

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

Añade transiciones de página nativas en tu app shell:

import '@capgo/capacitor-transitions';
import { initTransitions, setDirection, setupRouterOutlet } from '@capgo/capacitor-transitions/react';

initTransitions({ platform: 'auto' });

Envuelve las páginas enrutadas en cap-router-outlet, cap-page, y cap-content, y llama setDirection('forward') o setDirection('back') antes router.push() o router.back(). No dupliques headers o footers web si la navegación nativa ya gestiona esas áreas.

Consulta las guías completas: Usando @capgo/capacitor-native-navigation y Usando @capgo/capacitor-transitions.

Safe areas con Tailwind

Para las safe areas en Tailwind CSS, usa @capgo/tailwind-capacitor (publicado como tailwind-capacitor en npm). Proporciona safe-areas utilidades y otros plugins de Tailwind compatibles con Capacitor:

bun add -D tailwind-capacitor

En styles/globals.css:

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

Usa utilidades como pt-safe, pb-safe, y px-safe en lugar de añadir env(safe-area-inset-*) a mano. El proyecto se desarrolla activamente; si falta algo para tu configuración de Next.js, abre un PR en GitHub.

Cómo solucionar problemas de layout en iOS (Viewport, Safe Area y desbordamiento horizontal)

Si el contenido se ve recortado, desplazado o con scroll horizontal en iOS, añadir más overflow-x: hidden o ajustar solo la etiqueta viewport no suele solucionarlo. Revisa estas comprobaciones en orden.

Asegúrate de que la etiqueta meta viewport esté aplicada correctamente

App Router (app/): export viewport de app/layout.tsx:

import type { Viewport } from 'next';

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

Pages Router (pages/): coloca la meta tag del viewport en pages/_app.tsx, no _document.tsx (Es posible que Next.js no aplique las etiquetas de _document.tsx la forma que esperas para el comportamiento del viewport).

Gestiona el safe area de iOS desde un único wrapper raíz

Crea un app shell único y aplica el padding del safe area ahí, no en múltiples componentes anidados:

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

Envuelve todo el contenido de la página dentro de .app-shell. El padding de safe-area duplicado en headers, modales y wrappers de layout suele hacer que la UI parezca recortada o demasiado grande.

Con @capgo/tailwind-capacitor, puedes aplicar el mismo padding con utilidades como pt-safe pb-safe px-safe en ese único shell.

Configura Capacitor iOS contentInset a never primero

En capacitor.config.ts, prefiere desactivar el inset nativo y dejar que CSS (o la navegación nativa) contentInsetMode: 'css') se encarga del safe area:

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

Mezclar el content inset automático de Capacitor con CSS env(safe-area-inset-*) padding suele causar espacios dobles.

Encuentra el elemento real que desborda

El culpable habitual es un elemento que usa 100vw, Tailwind w-screen, un ancho fijo en píxeles, o un min-width.

En Safari Web Inspector, ejecuta:

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

Con Tailwind, reemplaza w-screen con w-full siempre que puedas. Muchos problemas de desbordamiento horizontal vienen de 100vw / w-screen, padding de safe-area duplicado, o un contenedor de ancho fijo —no del propio meta tag del viewport.

Optimización de rendimiento

Para garantizar el rendimiento óptimo de tu app con Next.js y Capacitor, considera estas buenas prácticas:

  • Minimiza el tamaño de la app eliminando assets y dependencias que no uses.
  • Optimiza imágenes y otros archivos multimedia para reducir los tiempos de carga.
  • Implementa lazy loading en componentes y páginas para mejorar la carga inicial.
  • Usa server-side rendering (SSR) con Next.js para mejorar la velocidad de carga y el SEO.
  • Aprovecha las optimizaciones nativas de Capacitor, como el caching de la web view y el app bundling.

Conclusión

Has convertido con éxito tu web app de Next.js en apps nativas de iOS y Android con Capacitor 8. Tu codebase ahora corre de forma nativa en móviles con acceso a las APIs del dispositivo.

Lo que lograste:

  • Configuración de Next.js para exportación estática
  • Añadido Capacitor 8 con plugins esenciales
  • Build y despliegue en simuladores iOS y Android
  • Live reload habilitado para desarrollo
  • Corrección de errores de layout en iOS (viewport, safe area, overflow)
  • UI con sensación nativa con Capgo Native Navigation and Transitions

Próximos pasos:

  • Configurar Capgo para actualizaciones OTA sin reenviar a la App Store
  • Añadir más plugins nativos como Camera, Geolocation o Push Notifications
  • Configura los iconos y splash screens para producción
  • Prepara tu app para enviarla a App Store y Google Play

¿Empiezas un proyecto desde cero? Mira Cómo crear una app móvil con Next.js desde cero para un tutorial paso a paso.

Recursos

Descubre cómo Capgo te ayuda a crear mejores apps más rápido, regístrate para obtener una cuenta gratis hoy mismo.

Sigue leyendo: Convertir tu app de Next.js a iOS y Android con Capacitor 8

Si estás usando Convierte tu app de Next.js a iOS y Android con Capacitor 8 para planificar el trabajo del plugin nativo, conéctalo con Directorio de plugins de Capgo para el flujo de trabajo de productos en el Capgo Plugin Directory, Plugins de Capacitor por Capgo para los detalles de implementación en Plugins de Capacitor por Capgo, Añadir o actualizar plugins para los detalles de implementación en Añadir o actualizar plugins, Alternativas a los plugins de Ionic Enterprise para el flujo de trabajo del producto en Alternativas a los plugins de Ionic Enterprise, y Native Builds de Capgo para el flujo de trabajo en Capgo Native Builds.

Live Updates para apps de Capacitor

Si hay un bug en la capa web, publica el fix con Capgo en lugar de esperar días a la aprobación de la app store. Los usuarios reciben la actualización en segundo plano mientras los cambios nativos siguen el proceso de revisión normal.

Lo último de nuestro blog

Capgo te da los mejores insights para crear una app móvil realmente profesional.