Introduzione
Hai già un'applicazione web in Next.js? In questa guida imparerai come trasformarla in app native per iOS e Android utilizzando Capacitor 8 — l'ultima versione con performance migliorate e nuove funzionalità.
Capacitor incapsula la tua web app in un container nativo, dandoti accesso alle API del dispositivo come fotocamera, filesystem e notifiche push, mantenendo invariata la tua codebase React. A differenza di React Native, non devi riscrivere nulla: il tuo code Next.js funziona così com'è.
Cosa imparerai:
- Configurare la tua app Next.js esistente per l'export statico
- Aggiungere Capacitor 8 con i plugin nativi essenziali
- Build e test sui simulatori iOS e Android
- Abilitare il live reload per uno sviluppo più rapido
- Risolvere i problemi di layout comuni su iOS (viewport, safe area, overflow orizzontale)
- Aggiungere una UI dall'aspetto nativo con Capgo Native Navigation and Transitions
Vuoi iniziare un nuovo progetto da zero? Dai un'occhiata alla nostra guida su Creare un'app mobile Next.js da zero.
Vantaggi di usare Next.js e Capacitor
- Riutilizzabilità di Code: Next.js ti permette di scrivere componenti riutilizzabili e condividere code tra le tue app web e mobile, risparmiando tempo e fatica nello sviluppo.
- Prestazioni: Next.js offre ottimizzazioni integrate delle performance, come il server-side rendering e il code splitting, garantendo tempi di caricamento rapidi e un'esperienza utente fluida.
- Capacità native: Capacitor dà accesso alle funzionalità native del dispositivo come fotocamera, geolocalizzazione e molto altro, permettendoti di creare app mobile ricche di funzionalità.
- Sviluppo semplificato: Con Capacitor, puoi sviluppare e testare la tua app mobile usando tecnologie web familiari, riducendo la curva di apprendimento e ottimizzando il processo di sviluppo.
Prerequisiti
Prima di iniziare, assicurati di avere:
- Node.js 18+ installato
- Un esistente Next.js 15+ applicazione
- Xcode (per lo sviluppo iOS, solo macOS)
- Android Studio (per lo sviluppo Android)
Configurare la tua app Next.js per il mobile
Il primo passo è configurare la tua app Next.js per l'export statico. Capacitor richiede file HTML/JS/CSS statici per il bundle nell'app nativa.
Apri il tuo next.config.js (o next.config.ts) file e aggiungi la configurazione di export:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
images: {
unoptimized: true,
},
};
module.exports = nextConfig;
Il output: 'export' l'impostazione indica a Next.js di generare file HTML statici e images: { unoptimized: true } salta l'ottimizzazione delle immagini di Next.js, che richiede un server.
Importante: Se usi funzionalità che richiedono un server (API route, server components con data fetching, ecc.), dovrai rifattorizzarle con alternative client-side o API esterne.
Aggiungi gli script specifici per mobile al tuo 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"
}
}
Testa l'export statico eseguendo:
bun run build
Dovresti vedere una cartella out nella root del progetto. Contiene tutti i file statici che Capacitor includerà nella tua app nativa.
Aggiungere Capacitor 8 al tuo progetto
Per impacchettare la tua app Next.js in un container mobile nativo, segui questi passaggi:
- Installa Capacitor core e CLI:
bun add @capacitor/core
bun add -D @capacitor/cli
- Installa i plugin Capacitor comuni che probabilmente ti serviranno:
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/preferences
Questi plugin offrono funzionalità essenziali:
- @capacitor/app: Gestisci gli eventi del ciclo di vita dell'app (foreground/background, URL)
- @capacitor/keyboard: Controllo del comportamento della tastiera su mobile
- @capacitor/splash-screen: Gestione della splash screen nativa
- @capacitor/preferences: Salvataggio persistente di dati key-value
- Inizializza Capacitor con i dettagli del progetto:
bunx cap init my-app com.example.myapp --web-dir out
Sostituisci my-app con il nome della tua app e com.example.myapp con il tuo app ID (notazione reverse domain).
- Crea o aggiorna il
capacitor.config.tsfile con la configurazione corretta:
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;
- Installa le piattaforme native:
bun add @capacitor/ios @capacitor/android
- Aggiungi le cartelle delle piattaforme native:
bunx cap add ios
bunx cap add android
Capacitor creerà le ios e android cartelle nella root del tuo progetto contenenti i progetti nativi.
Per buildare il progetto Android, ti serve Android Studio. Per iOS, serve un Mac con Xcode.
- Build e sync del progetto:
bun run mobile
Questo esegue il tuo script personalizzato che builda il progetto Next.js e sincronizza i file statici con le piattaforme native.
Build e deployment di app native
Per buildare e distribuire la tua app mobile nativa, segui questi passaggi: Per sviluppare app iOS, devi avere Xcode installato, mentre per le app Android devi avere Android Studio installato. Inoltre, se intendi distribuire la tua app sugli store, devi iscriverti all'Apple Developer Program per iOS e alla Google Play Console per Android.
- Apri i progetti nativi:
Per iOS:
bun run mobile:ios
Per Android:
bun run mobile:android
Oppure direttamente con Capacitor CLI:
bunx cap open ios
bunx cap open android
- Build e avvia l'app:

-
In Android Studio, attendi che il progetto sia pronto, quindi clicca sul pulsante “Run” per distribuire l'app su un dispositivo connesso o un emulatore.

-
In Xcode, configura il tuo account di firma per distribuire l'app su un dispositivo reale. Se non l'hai mai fatto, Xcode ti guiderà nel processo (nota che devi essere iscritto all'Apple Developer Program). Una volta configurato, clicca sul pulsante “Play” per avviare l'app sul dispositivo connesso.
Congratulazioni! Hai distribuito con successo la tua web app Next.js su un dispositivo mobile.
Live Reload con Capacitor
Durante lo sviluppo, puoi sfruttare il live reloading per vedere le modifiche istantaneamente sul tuo dispositivo mobile. Per abilitare questa funzione, segui questi passaggi:
- Trova il tuo indirizzo IP locale:
-
Su macOS, esegui il seguente comando nel terminale:
ipconfig getifaddr en0 -
Su Windows, esegui:
ipconfigCerca l'indirizzo IPv4 nell'output.
- Aggiorna il tuo
capacitor.config.tsper puntare al tuo server di sviluppo:
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;
Sostituisci YOUR_IP_ADDRESS con il tuo indirizzo IP locale (es. 192.168.1.100).
- Applica le modifiche al tuo progetto nativo:
bunx cap copy
Il copy il comando copia la cartella web e le modifiche di configurazione nel progetto nativo senza aggiornare l'intero progetto.
- Ricompila ed esegui l'app sul tuo dispositivo usando Android Studio o Xcode.
Ora, ogni volta che apporterai modifiche alla tua app Next.js, l'app mobile si ricaricherà automaticamente per rifletterle.
Nota: se installi nuovi plugin o modifichi file nativi, dovrai ricostruire il progetto nativo, poiché il live reloading si applica solo alle modifiche web code.
Utilizzo dei plugin Capacitor
I plugin di Capacitor ti permettono di accedere alle funzionalità native del dispositivo dalla tua app Next.js. Vediamo come usare il Plugin di condivisione come esempio:
- Installa il plugin Share:
bun add @capacitor/share
- Aggiorna il
pages/index.jsfile per usare il 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>
);
}
- Sincronizza le modifiche con il progetto nativo:
Come accennato prima, quando installi nuovi plugin devi eseguire un'operazione di sync e poi ridistribuire l'app sul dispositivo. Per farlo, esegui questo comando:
bun run mobile
Oppure sincronizza senza rebuild:
bunx cap sync
- Esegui il rebuild e avvia l'app sul tuo dispositivo.
Ora, quando clicchi sul pulsante “Share now!”, apparirà il dialog nativo di condivisione, permettendoti di condividere il contenuto con altre app.
Ho lavorato per anni con Ionic per creare applicazioni cross-platform, ma integrarlo con Next.js è complicato e raramente ne vale la pena se hai già Tailwind CSS 4.
Per un feeling mobile nativo in un'app Next.js + Capacitor, usa i plugin Capgo invece di UI kit solo web come Konsta UI:
- @capgo/capacitor-native-navigation — navbar nativa, Liquid Glass tab bar su iOS e uno stile tab bar sfocato su Android. Il router di Next.js mantiene lo stato delle rotte; il plugin gestisce la UI nativa.
- @capgo/capacitor-transitions — transizioni di pagina in stile Ionic e swipe-back dal bordo su iOS nel layer WebView, senza adottare Ionic UI.
Installa entrambi:
bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync
Configura la navigazione nativa con la modalità CSS inset, così il contenuto web rispetta le barre native:
import { NativeNavigation } from '@capgo/capacitor-native-navigation';
await NativeNavigation.configure({
contentInsetMode: 'css',
animationDuration: 360,
glass: {
effect: 'liquidGlass',
},
});
Renderizza una tab bar Liquid Glass (iOS usa il rendering di sistema; Android usa un backdrop WebView sfocato):
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}`);
});
Aggiungi transizioni di pagina native nell'app shell:
import '@capgo/capacitor-transitions';
import { initTransitions, setDirection, setupRouterOutlet } from '@capgo/capacitor-transitions/react';
initTransitions({ platform: 'auto' });
Avvolgi le pagine del router in cap-router-outlet, cap-page, e cap-content, e chiama setDirection('forward') o setDirection('back') prima router.push() o router.back(). Non duplicare header o footer web quando la navigazione nativa gestisce quelle superfici.
Guarda le guide complete: Usando @capgo/capacitor-native-navigation e Uso di @capgo/capacitor-transitions.
Safe areas con Tailwind
Per le safe area dei dispositivi in Tailwind CSS, usa @capgo/tailwind-capacitor (pubblicato come tailwind-capacitor su npm). Fornisce safe-areas utility e altri plugin Tailwind compatibili con Capacitor:
bun add -D tailwind-capacitor
In styles/globals.css:
@import 'tailwindcss';
@plugin "@capgo/tailwind-capacitor/platform";
@plugin "@capgo/tailwind-capacitor/safe-areas";
Usa utility come pt-safe, pb-safe, e px-safe invece di spargere env(safe-area-inset-*) a mano. Il progetto è in fase di sviluppo attivo — se manca qualcosa per il tuo setup Next.js, apri una PR su GitHub.
Risolvere problemi di layout su iOS (Viewport, Safe Area e overflow orizzontale)
Se i contenuti appaiono tagliati, spostati o con scroll orizzontale su iOS, aggiungere più overflow-x: hidden o modificare il tag viewport di solito non basta. Segui questi controlli in ordine.
Assicurati che il meta tag viewport sia applicato correttamente
App Router (app/): export viewport da app/layout.tsx:
import type { Viewport } from 'next';
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
viewportFit: 'cover',
};
Pages Router (pages/): inserisci il meta tag viewport in pages/_app.tsx, non _document.tsx (Next.js potrebbe non applicare i tag da _document.tsx come ti aspetti per il comportamento del viewport).
Gestisci la safe area di iOS da un unico wrapper root
Crea un unico app shell e applica lì il padding per la safe area — non in più componenti annidati:
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);
}
Racchiudi tutto il contenuto della pagina in .app-shell. Il padding della safe-area duplicato in header, modal e wrapper del layout spesso fa apparire l'interfaccia tagliata o troppo grande.
Con @capgo/tailwind-capacitor, puoi applicare lo stesso padding con utility come pt-safe pb-safe px-safe su quella singola shell.
Imposta Capacitor iOS contentInset a never per primo
In capacitor.config.ts, preferisci disabilitare i native inset e lascia che il CSS (o quella contentInsetMode: 'css'di Native Navigation) gestisca la safe area:
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'out',
ios: {
contentInset: 'never',
},
};
Mescolare l'automatic content inset di Capacitor con il CSS env(safe-area-inset-*) il padding è una causa comune di spaziature doppie.
Trova il vero elemento che causa l'overflow
Il colpevole di solito è un elemento che usa 100vw, Tailwind w-screen, una larghezza fissa in pixel o un grande min-width.
In Safari Web Inspector, esegui:
[...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, sostituisci w-screen con w-full quando possibile. Molti problemi di overflow orizzontale derivano da 100vw / w-screen, padding della safe-area duplicato o un contenitore a larghezza fissa — non dal meta tag viewport stesso."
Ottimizzazione delle performance
Per garantire prestazioni ottimali alla tua app Next.js e Capacitor, segui queste best practice:
- Riduci al minimo la dimensione dell'app eliminando asset e dipendenze inutilizzate.
- Ottimizza immagini e altri file multimediali per ridurre i tempi di caricamento.
- Implementa il lazy loading per componenti e pagine per migliorare le performance di caricamento iniziale.
- Usa il server-side rendering (SSR) con Next.js per velocizzare il caricamento e migliorare la SEO.
- Sfrutta le ottimizzazioni integrate di Capacitor, come il caching della web view e l'app bundling.
Conclusione
Hai convertito con successo la tua web app Next.js in app native iOS e Android con Capacitor 8. Il tuo codebase web ora gira nativamente su mobile con accesso alle API del dispositivo.
Cosa hai realizzato:
- Configurato Next.js per l'export statico
- Aggiunto Capacitor 8 con plugin essenziali
- Build e deploy su simulatori iOS e Android
- Abilitato il live reload per lo sviluppo
- Risolti i comuni problemi di layout iOS (viewport, safe area, overflow)
- Aggiunta una UI nativa con Capgo Native Navigation and Transitions
Prossimi passi:
- Configurazione Capgo per aggiornamenti over-the-air senza resubmission sugli store
- Aggiungi altri plugin nativi come Camera, Geolocation o Push Notifications
- Configura icone dell'app e splash screen per la produzione
- Prepara la tua app per l'invio su App Store e Google Play
Vuoi iniziare un nuovo progetto? Dai un'occhiata a Creare un'app mobile Next.js da zero per una guida passo dopo passo.
Risorse
- Documentazione di Next.js
- @capgo/capacitor-native-navigation — tab bar Liquid Glass e chrome nativo
- Documentazione di Capacitor 8
- @capgo/capacitor-transitions — transizioni di pagina dall'aspetto nativo
- @capgo/tailwind-capacitor — Utility safe-area di Tailwind per Capacitor
- Capgo - Live Updates per app Capacitor
Scopri come Capgo può aiutarti a creare app migliori più velocemente, registrati per un account gratuito oggi.
Continua da Converti la tua app Next.js in iOS e Android con Capacitor 8
Se stai usando Converti la tua app Next.js in iOS e Android con Capacitor 8 per pianificare il lavoro sui plugin nativi, collegalo a Directory dei plugin di Capgo per il workflow del prodotto nella Capgo Plugin Directory, Plugin Capacitor di Capgo per i dettagli di implementazione in Capacitor Plugins di Capgo, Aggiunta o aggiornamento dei plugin per i dettagli sull'implementazione in Adding or Updating Plugins, Alternative ai plugin Ionic Enterprise per il workflow del prodotto in Ionic Enterprise Plugin Alternatives, e Capgo Native Build per il workflow di prodotto in Capgo Native Builds.