Saltare al contenuto principale
Guida pratica

Crea un'app mobile Next.js da zero con Capacitor 8

Guida passo dopo passo per creare un nuovo progetto Next.js 15 e trasformarlo in app mobili native per iOS e Android utilizzando Capacitor 8. Perfetto per iniziare con lo sviluppo mobile-first.

Crediti dell'articolo

Martin Donadieu

Autore

Valeria

Recensore

Jordan

Curatore

Crea un'app mobile Next.js da zero con Capacitor 8

Introduzione

Vuoi creare un'app mobile con Next.js da zero? Questa guida ti guida nella creazione di un nuovo progetto Next.js 15 configurato per la mobilità fin dal primo giorno, quindi pacchettizzato come app native iOS e Android utilizzando Capacitor 8.

Al termine di questo tutorial, avrai un'app mobile funzionante che esegue su simulatori e che potrai continuare a sviluppare e pubblicare infine sullo Store App e su Google Play.

Tempo richiesto: ~30 minuti

Cosa costruirai:

  • Un nuovo progetto Next.js 15 con App Router
  • Configurazione di esportazione statica per la mobilità
  • Capacitor 8 with essential plugins
  • App native iOS e Android
  • Setup di sviluppo con live reload

Già hai un'app Next.js? Converti la tua app Next.js in mobile altrimenti.

Prerequisiti

Assicurati di avere installati:

  • Node.js 18+ (controlla con node --version)
  • Bun gestore dei pacchetti (curl -fsSL https://bun.sh/install | bash)
  • Xcode (solo per macOS, per lo sviluppo di iOS)
  • Android Studio (per lo sviluppo di Android)

Passo 1: Crea un nuovo progetto Next.js

Inizia creando un progetto Next.js 15 fresco:

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

Quando viene richiesto, seleziona queste opzioni:

  • TypeScript: Sì (consigliato)
  • ESLint:
  • Tailwind CSS: Sì (consigliato per la stilizzazione mobile)
  • src/ directory:
  • Router dell'applicazione: Sì (consigliato)
  • Alias di importazione: Predefinito (@/*)

Vai al tuo progetto:

cd my-mobile-app

Passo 2: Configura Next.js per l'esportazione statica

Capacitor richiede file HTML/JS/CSS statici. Configura Next.js per l'esportazione statica aggiornando 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;

Perché questi impostazioni?

  • output: 'export' — Genera HTML statico invece di richiedere un server Node.js
  • images: { unoptimized: true } — Disabilita l'ottimizzazione delle immagini di Next.js (richiede un server)
  • trailingSlash: true — Assicura una routing corretta nella WebView nativa

Passo 3: Aggiungi script mobili

Aggiorna il tuo package.json con gli script di sviluppo mobile:

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

Testa la costruzione:

bun run build

Devi vedere una cartella con i tuoi file statici. out Passo 4: Installa __CAPGO_KEEP_0__ 8

Installare i pacchetti di base di Capacitor:

Install the Capacitor core packages:

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

Quello che fanno questi plugin:

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

@__CAPGO_KEEP_0__/app

  • @capacitor/app @__CAPGO_KEEP_0__/keyboard
  • @capacitor/app — Controllo del comportamento della tastiera
  • @capacitor/schermo di benvenuto — Controllo dello schermo di benvenuto nativo
  • @capacitor/barra dello stato — Personalizza la barra dello stato del dispositivo
  • @capacitor/preferenze — Archiviazione dei valori chiave (come localStorage ma nativa)

Passo 5: Inizializza Capacitor

Inizia Capacitor con i dettagli del tuo progetto:

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

Sostituisci:

  • "My Mobile App" con il nome della tua app
  • com.example.mymobileapp con l'ID dell'app (notazione di dominio inverso)

Questo crea capacitor.config.ts. Aggiornalo con la configurazione del plugin:

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;

Passo 6: Aggiungi piattaforme native

Installa i pacchetti delle piattaforme:

bun add @capacitor/ios @capacitor/android

Genera i progetti nativi:

bunx cap add ios
bunx cap add android

Questo crea ios e android directory contenenti i progetti nativi.

Passo 7: Costruisci e Esegui

Costruisci il tuo progetto e sincronizza con le piattaforme native:

bun run mobile

Apre in iOS Simulator:

bun run mobile:ios

O Android Emulator:

bun run mobile:android

In Xcode (iOS):

  1. Scegli un simulatore dal menu a discesa dei dispositivi
  2. Clicca sul pulsante di riproduzione o premi Cmd + R

In Android Studio:

  1. Aspetta che Gradle completi la sincronizzazione
  2. Scegli un emulatore dal menu a discesa dei dispositivi
  3. Clicca sul pulsante di esecuzione o premi Shift + F10

Passo 8: Configura Live Reload

Per un sviluppo più veloce, abilita la ricarica live in modo che le modifiche apparano istantaneamente sul tuo dispositivo.

  1. Cerca l'indirizzo IP locale:
# macOS
ipconfig getifaddr en0

# Windows
ipconfig
  1. Crea una configurazione di sviluppo locale Capacitor. Aggiungi a 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. Inizia il server di sviluppo e copia la configurazione al nativo:
bun run dev &
NODE_ENV=development bunx cap copy
  1. Riavvia in Xcode/Android Studio

Ora le modifiche ai tuoi Next.js code si ricaricheranno automaticamente sul dispositivo.

Passo 9: Crea la Prima Schermata Mobile

Creiamo una semplice schermata home adatta a dispositivi mobili. Aggiorna 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>
  );
}

Passo 10: Aggiungi Gestione Area Sicura

I dispositivi mobili hanno notch, indicatori di home e barre di stato. Aggiungi la gestione dell'area sicura con Tailwind.

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

Struttura del Progetto

Il tuo progetto dovrebbe avere ora questo aspetto:

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

Passaggi Successivi

Ora hai un'app mobile Next.js funzionante. Ecco cosa fare di seguito:

Configurazione Essenziale

  • Icône dell'applicazione: Sostituisci le icone predefinite in ios/App/App/Assets.xcassets e android/app/src/main/res
  • Pantalla di benvenuto: Personalizza in progetti nativi o utilizza @capacitor/splash-screen config
  • Collegamenti profondi: Configura i schemi di URL per il tuo app

Aggiungi più funzionalità

  • Camera: bun add @capacitor/camera
  • Posizionamento geografico: bun add @capacitor/geolocation
  • Notifiche push: bun add @capacitor/push-notifications
  • File System: bun add @capacitor/filesystem

Interfaccia nativa e transizioni

Usa invece dei plugin Capgo per un'esperienza mobile nativa:

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

Per aree sicure di Tailwind, aggiungi @capgo/tailwind-capacitor:

bun add -D tailwind-capacitor

Vedi Usare @capgo/capacitor-navigazione-nativa, Usare @capgo/capacitor-transizioniEcco, e il repo di tailwind-capacitor per la configurazione specifica di Next.js.

Risolvere i Problemi di Layout iOS (Viewport, Area di Sicurezza e Sovraffollamento Orizzontale)

Se il contenuto sembra essere tagliato, spostato o scorrevole orizzontalmente su iOS, aggiungere o modificare il tag viewport da solo non risolve di solito il problema. Esegui questi controlli in ordine. overflow-x: hidden Assicurati di aver applicato correttamente il tag meta viewport

Router dell'App

export (app/da viewport Router delle Pagine app/layout.tsx:

import type { Viewport } from 'next';

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

mettere il tag meta viewport in (pages/Risolvere i Problemi di Layout iOS (Viewport, Area di Sicurezza e Sovraffollamento Orizzontale) è un passo importante per creare applicazioni mobili performanti con Next.js e Capacitor. pages/_app.tsxe non _document.tsx.

Gestisci l'area sicura di iOS da un wrapper radice solo

Creare un unico guscio di applicazione e applicare il padding dell'area sicura lì — non nei componenti nidificati multipli:

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

Avvolgere tutta la content page all'interno di .app-shell. Il padding dell'area sicura duplicato nei titoli, nei modali e nei wrapper di layout spesso fa sembrare l'interfaccia utente tagliata o troppo grande.

Con @capgo/tailwind-capacitorpuoi esprimere lo stesso padding con utilità come pt-safe pb-safe px-safe su quel guscio unico.

Imposta Capacitor iOS contentInset su never context: Pagina/area: Pagina di prodotti con aggiornamenti in tempo reale. Ruolo: Etichetta di navigazione breve o elemento di navigazione. Chiave di messaggio `live_update_dynamic_label_to` (Etichetta di aggiornamento dinamico Live Update To).

In capacitor.config.ts, prefer native inset disabled e lascia che CSS (o la navigazione nativa) contentInsetMode: 'css') possieda l'area sicura:

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

Mischia l'inserimento automatico del contenuto di Capacitor con il padding CSS env(safe-area-inset-*) Trova l'elemento che sta effondando realmente

Il solito colpevole è un elemento che utilizza

, Tailwind 100vw, una larghezza in pixel fissata, o una larghezza w-screenIn Safari Web Inspector, esegui: min-width.

Con Tailwind, sostituisci

[...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 w-screen Find w-full quando possibile. Molti problemi di sovrapposizione orizzontale derivano da 100vw / w-screenpadding di area sicura duplicato, o da un contenitore di larghezza fissata — non dal tag meta del viewport stesso.

Aggiornamenti Over-the-Air

Configura Capgo per inviare aggiornamenti senza la riconferma dell'app store:

bunx @capgo/cli init

Risolvere i Problemi

contexto: Pagina/Area: Sezione di supporto o sezione di supporto premium della pagina o del footer. Ruolo: Intestazione di sezione o pagina. Visto in: pagina support-policy.astro. Chiave di messaggio `support_policy_troubleshooting_title` (Titolo della sezione di supporto per la politica di supporto). Costruzione fallita con “Non è stato trovato il modulo” bun install Esegui

e riprova. iOS: “Non è stato trovato alcun identità di firma”

Android: “SDK location not found” Crea android/local.properties con sdk.dir=/path/to/android/sdk

Le modifiche non si visualizzano sul dispositivo Assicurati di aver eseguito bun run mobile Dopo aver apportato modifiche. Per il live reload, verificare che l'indirizzo IP sia corretto e che il server di sviluppo sia in esecuzione.

Risorse

Sii pronto a spedire la tua app? Scopri come Capgo può aiutarti a consegnare aggiornamenti più velocemente — iscrivi gratuitamente oggi.

Continua da Costruisci un'app mobile Next.js da zero con Capacitor 8

Se stai utilizzando Costruisci un'app mobile Next.js da zero con Capacitor 8 per pianificare l'automazione CI/CD, connettilo con Capgo CI/CD per il flusso di lavoro del prodotto in Capgo CI/CD, Capgo Build nativi per il flusso di lavoro del prodotto in Capgo Build nativi, Capgo Integrazioni per il workflow del prodotto in Capgo Integrazioni Integrazione CI/CD per i dettagli di implementazione in Integrazione CI/CD, e GitHub Azioni Integrazione per i dettagli di implementazione in GitHub Azioni Integrazione.

Aggiornamenti in Tempo Reale per le app Capacitor

Quando un bug del layer web è attivo, invia la correzione attraverso Capgo invece di attendere giorni per l'approvazione della store. Gli utenti ricevono l'aggiornamento in background mentre le modifiche native rimangono nel normale percorso di revisione.

Sostegno umano da Martin

Inizia subito

Ultimi articoli dal nostro Blog

Capgo vi dà le migliori informazioni che avete bisogno per creare un'app mobile veramente professionale.