Introduzione
Vuoi creare un'app mobile con Next.js dall'alto in basso? Questa guida ti guida attraverso la creazione di un nuovo progetto Next.js 15 configurato per la mobilità fin dal primo giorno, quindi lo imballa come app native iOS e Android utilizzando Capacitor 8.
Al termine di questo tutorial, avrai un'app mobile funzionante che esegue i simulatori che puoi continuare a sviluppare e pubblicare eventualmente sul App Store e Google Play.
Tempo richiesto: ~30 minuti
Cosa costruisci:
- Un nuovo progetto Next.js 15 con App Router
- Configurazione di esportazione statica per la mobilità
- Capacitor 8 con plugin essenziali
- App native iOS e Android
- Setup di sviluppo con live reload
Già hai un'app Next.js? Ecco cosa fare Converti la tua app Next.js in mobile invece.
Requisiti
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 nuovo progetto Next.js 15:
bunx create-next-app@latest my-mobile-app
Quando viene richiesto, seleziona queste opzioni:
- TypeScript: Sì (consigliato)
- ESLint: Sì
- Tailwind CSS: Sì (consigliato per lo styling mobile)
src/directory: Sì- Router dell'applicazione: Sì (consigliato)
- Importa alias: Predefinito (
@/*)
Naviga al tuo progetto:
cd my-mobile-app
Passaggio 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.jsimages: { unoptimized: true }— Disabilita l'ottimizzazione delle immagini di Next.js (richiede un server)trailingSlash: true— Assicura la routing corretta nella WebView nativa
Passaggio 3: Aggiungi script mobili
Aggiorna il tuo package.json con 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"
}
}
Sviluppa l'installazione:
bun run build
Devi vedere un out directory con i tuoi file statici.
Passo 4: Installare Capacitor 8
Installare i pacchetti di base di Capacitor:
bun add @capacitor/core
bun add -D @capacitor/cli
Installare plugin essenziali che la maggior parte delle app mobili richiede:
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/status-bar @capacitor/preferences
Cosa fanno questi plugin:
- @capacitor/app — Eventi di ciclo di vita dell'applicazione (in primo piano/ in background, collegamenti profondi)
- @capacitor/keyboard — Control il comportamento della tastiera
- @capacitor/splash-screen — Controllo dello schermo di benvenuto nativo
- @capacitor/status-bar — Personalizza la barra dello stato del dispositivo
- @capacitor/preferences — 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 visualizzato dell'appcom.example.mymobileappcon 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 native:
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
Apri in iOS Simulator:
bun run mobile:ios
O Android Emulator:
bun run mobile:android
In Xcode (iOS):
- Scegli un simulatore dalla lista dispositivi
- Clicca sul pulsante di riproduzione o premi
Cmd + R
In Android Studio:
- Aspetta che Gradle si sincronizzi
- Scegli un emulatore dalla lista dispositivi
- Clicca sul pulsante di esecuzione o premi
Shift + F10
Passo 8: Configura Live Reload
Per una maggiore velocità di sviluppo, abilita live reload per visualizzare i cambiamenti istantaneamente sul tuo dispositivo.
- Cerca l'indirizzo IP locale:
# macOS
ipconfig getifaddr en0
# Windows
ipconfig
- Crea una configurazione di sviluppo 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;
- Avvia il server di sviluppo e copia la configurazione nativa:
bun run dev &
NODE_ENV=development bunx cap copy
- Riavvia in Xcode/Android Studio
Ora le modifiche al tuo Next.js code verranno ricaricate in tempo reale sul dispositivo.
Passo 9: Crea la Prima Schermata Mobile
Crea una semplice schermata di benvenuto per 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 ora avere 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 Fondamentale
- Icone dell'app: Sostituisci gli iconi predefiniti in
ios/App/App/Assets.xcassetseandroid/app/src/main/res - Schermo di benvenuto: Personalizza in progetti nativi o utilizza
@capacitor/splash-screenconfig - Collegamenti profondi: Configura i schemi di URL per il tuo app
Aggiungi più funzionalità
- Camera:
bun add @capacitor/camera - Geolocalizzazione:
bun add @capacitor/geolocation - Notifiche push:
bun add @capacitor/push-notifications - File System:
bun add @capacitor/filesystem
Interfaccia nativa e transizioni
Usa i plugin Capgo al posto di Konsta UI per un'esperienza mobile nativa:
- @capgo/capacitor-navigazione-nativa – Barra dei tab di vetro liquido e navbar nativa
- @capgo/capacitor-transizioni – Transizioni di pagina con un sentimento nativo
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 Utilizza @capgo/capacitor-navigazione-nativa, Utilizza @capgo/capacitor-transizioniEcco il repo tailwind-__CAPGO_KEEP_0__ per la configurazione specifica di Next.js. tailwind-capacitor repo Se il contenuto sembra essere tagliato, spostato o scorrevole orizzontalmente su iOS, aggiungere o modificare il tag viewport da solo non risolve il problema. Esegui questi controlli in ordine.
Assicurati che il meta tag viewport sia applicato correttamente.
Router di App overflow-x: hidden : esporta
da
: Router delle Pagine (app/: inserisci il meta tag viewport viewport tailwind-__CAPGO_KEEP_0__ repo per la configurazione specifica di Next.js. app/layout.tsx:
import type { Viewport } from 'next';
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
viewportFit: 'cover',
};
Per risolvere i problemi di layout su iOS (Viewport, Area di sicurezza e sovrapposizione orizzontale), (pages/Se il contenuto sembra essere tagliato, spostato o scorrevole orizzontalmente su iOS, aggiungere o modificare il tag viewport da solo non risolve il problema. Esegui questi controlli in ordine. Assicurati che il meta tag viewport sia applicato correttamente. App Router,): esporta da Pages Router,): inserisci il meta tag viewport pages/_app.tsxNon gestire l'area sicura di iOS da un unico wrapper radice _document.tsx.
Creare un unico guscio di app e applicare il padding dell'area sicura lì — non nei componenti nidificati multipli:
Avvolgere tutta il contenuto della pagina all'interno
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);
}
La duplicazione del padding dell'area sicura nei titoli, nei modali e nei wrapper di layout spesso fa sembrare l'interfaccia utente tagliata o troppo grande. .app-shellCon
@__CAPGO_KEEP_0__/tailwind-__CAPGO_KEEP_1__ @capgo/tailwind-capacitorsu quel guscio unico. pt-safe pb-safe px-safe Imposta __CAPGO_KEEP_0__ iOS
Set Capacitor iOS contentInset primo never Non
In capacitor.config.ts, prefer native inset disabled e lascia che CSS (o la navigazione nativa) gestisca l'area sicura: contentInsetMode: 'css'Mixing __CAPGO_KEEP_0__’s automatic content inset con CSS
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'out',
ios: {
contentInset: 'never',
},
};
Mixing Capacitor’s automatic content inset with CSS env(safe-area-inset-*) Trova l'elemento che sta veramente sovrapponendosi
L'elemento colpevole è spesso un elemento che utilizza
, Tailwind 100vw, una larghezza in pixel fissata, o un valore molto 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 with w-full quando possibile. Molti problemi di sovrapposizione orizzontale derivano da 100vw / w-screen, sovrapposizione di padding di area sicura duplicata, o da un contenitore di larghezza fissata — non dal tag meta viewport stesso.
Aggiornamenti Over-the-Air
Configura Capgo per inviare aggiornamenti senza dover ricondividere l'app sullo store:
bunx @capgo/cli init
Risoluzione dei problemi
Errore di compilazione con “Cannot find module”
Esegui bun install e riprova.
iOS: “Non trovato identità di firma” Apri Xcode, vai a Signing & Capabilità, e seleziona il tuo team di sviluppo.
Android: “SDK location not found”
Crea android/local.properties con sdk.dir=/path/to/android/sdk
I cambiamenti non vengono visualizzati sul dispositivo
Assicurati di aver eseguito bun run mobile dopo aver fatto le modifiche. Per il live reload, verificare l'indirizzo IP è corretto e il server di sviluppo è in esecuzione.
Risorse
- Capacitor 8 Documentazione
- Next.js 15 Documentazione
- Capgo - Aggiornamenti in tempo reale
- @capgo/capacitor-navigazione nativa
- @capgo/capacitor-transizioni
- @capgo/tailwind-capacitor
Pronto a spedire la tua app? Impara come Capgo può aiutarti a consegnare aggiornamenti più velocemente — iscriversi a un account gratuito 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 Costruzioni native per il flusso di lavoro del prodotto in Capgo Costruzioni native, Integrazioni Capgo per il workflow del prodotto in Integrazioni Capgo Integrazione CI/CD per il dettaglio di implementazione in Integrazione CI/CD Integrazione GitHub Actions per il dettaglio di implementazione in Integrazione GitHub Actions.