Introduzione
Vuoi creare un'app mobile con Next.js dall'alto in basso? Questo tutorial 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 che puoi continuare a sviluppare e pubblicare infine sullo Store App e Google Play.
Tempo richiesto: ~30 minuti
Cosa costruirai:
- Un nuovo progetto Next.js 15 con App Router
- Static export configuration for mobile
- Capacitor 8 con plugin essenziali
- Applicazioni native per iOS e Android
- Ricarica in tempo reale di sviluppo
Hai già un'app Next.js? Consulta Converti la tua app Next.js in mobile altrimenti.
Prerequisites
Assicurati di avere installati:
- Node.js 18+ (controlla con
node --version) - Bun gestore di 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: Sì
- Tailwind CSS: Sì (consigliato per lo styling mobile)
src/directory: Sì- Router dell'app: Sì (consigliato)
- Alias di importazione: Default (
@/*)
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.jsimages: { 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 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 build:
bun run build
Devi vedere un out directory con i tuoi file statici.
Passo 4: Installa Capacitor 8
Installa i pacchetti di base di Capacitor:
bun add @capacitor/core
bun add -D @capacitor/cli
Installare i plugin essenziali per la maggior parte degli app mobili:
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/status-bar @capacitor/preferences
Di cosa si tratta questi plugin:
- /@capacitor/app Eventi di ciclo di vita dell'app (in primo piano/trasparenza, link profondi)
- @capacitor/keyboard – Controllo del comportamento della tastiera
- @capacitor/splash-screen – Controllo dello schermo di benvenuto nativo
- @capacitor/barra dello stato – Stilizzazione della barra di stato del dispositivo
- @ capacitor /preferenze — Archiviazione chiave-valore (come localStorage ma nativa)
Passo 5: Inizializza Capacitor
Initialize Capacitor with your project details:
bunx cap init "My Mobile App" com.example.mymobileapp --web-dir out
Replace:
"My Mobile App"con il nome di schermo del tuo'applicazionecom.example.mymobileappcon il tuo ID dell'applicazione (notazione di dominio inverso)
Questo crea capacitor.config.tsAggiornalo 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;
Aggiornalo con la configurazione del plugin:
Passo 6: Aggiungi 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
Apre in iOS Simulator:
bun run mobile:ios
O Android Emulator:
bun run mobile:android
In Xcode (iOS):
- Seleziona un simulatore dal menu a discesa dei dispositivi
- Clicca sul pulsante Play o premi
Cmd + R
In Android Studio:
- Attendere che Gradle finisca di sincronizzare
- Seleziona un emulatore dal menu dispositivo
- Clicca sul pulsante Esegui o premi
Shift + F10
Passo 8: Configura Live Reload
Abilita il reload in tempo reale per ottenere risultati più rapidi.
- 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;
- Esegui 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 si ricollegheranno automaticamente sul dispositivo.
Passo 9: Crea la Prima Schermata Mobile
Creiamo una semplice schermata di benvenuto mobile-friendly. 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
Dispositivi mobili hanno notch, indicatori di home e barre di stato. Aggiungi il trattamento dell'area sicura con Tailwind.
Aggiornamento 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
La tua progettazione dovrebbe ora assomigliare a questo:
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
└── ...
Next Steps
Ora hai un'app mobile Next.js funzionante. Ecco cosa fare dopo:
Configurazione essenziale
- Icone dell'app: Sostituisci gli iconi predefiniti in
ios/App/App/Assets.xcassetsEandroid/app/src/main/res - Schermo di avvio: Personalizza in progetti nativi o utilizza
@capacitor/splash-screenconfig - Deep Links: Configura i schemi di URL per la tua app
Aggiungi più funzionalità
- Camera:
bun add @capacitor/camera - Geolocalizzazione:
bun add @capacitor/geolocation - Notifiche push:
bun add @capacitor/push-notifications - Sistema di file:
bun add @capacitor/filesystem
Interfaccia utente nativa e transizioni
Utilizza i plugin Capgo al posto di Konsta UI per un aspetto mobile nativo:
- @capgo/capacitor-navigazione-nativa — Barra dei tasti Liquido Glass 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 Utilizzo di @capgo/capacitor-navigazione nativa, Utilizzo di @capgo/capacitor-transizioni, e il repo tailwind-capacitor per la configurazione specifica di Next.js.
Risoluzione dei problemi di layout di iOS (Viewport, Area sicura e sovrapposizione orizzontale)
Se il contenuto sembra essere tagliato, spostato o scorrevole orizzontalmente su iOS, aggiungere più overflow-x: hidden o semplicemente aggiustare la tag viewport non risolve il problema. Esegui questi controlli in ordine.
Assicurati che il tag meta viewport sia applicato correttamente.
Router dell'app (app/export viewport da app/layout.tsx:
import type { Viewport } from 'next';
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
viewportFit: 'cover',
};
Router delle pagine (pages/mettere il tag meta viewport in pages/_app.tsx, non _document.tsx.
Trattare l'area di sicurezza di iOS da un solo wrapper radice
Creare un unico guscio dell'applicazione e applicare il padding dell'area di sicurezza lì — non in 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 il contenuto della pagina dentro .app-shellLa duplicazione dello spazio di sicurezza nella zona superiore spesso fa apparire l'interfaccia utente tagliata o troppo grande.
With @capgo/tailwind-capacitor, puoi esprimere la stessa spaziatura con utilità come pt-safe pb-safe px-safe on che singola shell.
Imposta Capacitor iOS contentInset su never first
primo capacitor.config.tspreferare l'interfaccia nativa disabilitata e lasciare che CSS (o la navigazione nativa) contentInsetMode: 'css'Possiedere l'area di sicurezza
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'out',
ios: {
contentInset: 'never',
},
};
Mixing Capacitor’s automatic content inset con CSS env(safe-area-inset-*) Mischia __CAPGO_KEEP_0__’s automatico contenuto insetto con CSS
Trova l'elemento sovraccarico reale
Il solito colpevole è un elemento che utilizza 100vw, Tailwind w-screen, una larghezza in pixel fissata, 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 sovraccarico orizzontale derivano da 100vw / w-screen, padding di area sicura duplicato, o un contenitore di larghezza fissata — non dal tag meta viewport stesso.
Aggiornamenti Over-the-Air
Configura Capgo per aggiornare le applicazioni senza doverle riscaricare sullo store:
bunx @capgo/cli init
Risolvere i problemi
Costruzione fallita con “Cannot find module”
Esegui bun install e provare di nuovo.
iOS: "Identità di firma non trovata" Apri Xcode, vai a Signing & Capabilità, e seleziona il tuo team di sviluppo.
Android: “SDK non trovato”
Create android/local.properties Crea sdk.dir=/path/to/android/sdk
Modifiche non visibili sul dispositivo
Le modifiche non si visualizzano sul dispositivo bun run mobile dopo aver effettuato modifiche. Verifica l'indirizzo IP per il live reload e assicurati che il server di sviluppo sia in esecuzione.
Risorse
- Capacitor 8 Documentazione
- Documentazione Next.js 15
- Capgo - Aggiornamenti in tempo reale
- @capgo/capacitor-navigazione nativa
- @capgo/capacitor-transizioni
- @capgo/tailwind-capacitor
Pronto a spedire la tua app? Scopri come Capgo possa aiutarti a consegnare aggiornamenti più velocemente — iscrivi il tuo account gratuito oggi.
Continua da Costruisci un'app mobile Next.js da zero con Capacitor 8
If sei stai utilizzando Crea 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, Capgo Integrazioni per il workflow del prodotto nelle Capgo Integrazioni Integrazione CI/CD per i dettagli di implementazione nella integrazione CI/CD, e context: Pagina del prodotto Capgo Builder / costruzione cloud nativa. Ruolo: Etichetta di UI breve o elemento di navigazione. Chiave di messaggio `native_build_feature_ci_cd` (Caratteristica di costruzione nativa Ci Cd). Integrazione CI/CD, e per il dettaglio di implementazione in Integrazione CI/CD, e GitHub Integrazione azioni per i dettagli di implementazione in GitHub Azioni di integrazione.