Introduction
Vous souhaitez créer une application mobile avec Next.js à partir de zéro ? Ce guide vous accompagne dans la création d'un projet Next.js 15 entièrement configuré pour les appareils mobiles dès le départ, puis dans la création de versions natives iOS et Android à l'aide de Capacitor 8.
Par la fin de ce tutoriel, vous disposerez d'une application mobile fonctionnelle exécutée sur des simulateurs que vous pouvez continuer à développer et publier ultérieurement sur l'App Store et Google Play.
Temps requis : ~30 minutes
Ce que vous allez construire :
- Un nouveau projet Next.js 15 avec App Router
- Configuration d'exportation statique pour les appareils mobiles
- Capacitor 8 avec plugins essentiels
- Applications iOS et Android natifs
- Configuration de développement avec rechargement en direct
Avez-vous déjà un application Next.js ? Consultez Convertir votre application Next.js en mobile au lieu de cela.
Prérequis
Assurez-vous d'avoir ces éléments installés :
- Node.js 18+ (vérifiez avec
node --version) - Bun gestionnaire de packages (
curl -fsSL https://bun.sh/install | bash) - Xcode (macOS uniquement, pour le développement iOS)
- Android Studio (pour le développement Android)
Étape 1 : Créer un nouveau projet Next.js
Commencez par créer un projet Next.js 15 frais :
bunx create-next-app@latest my-mobile-app
Lorsque vous êtes invité à choisir, sélectionnez ces options :
- TypeScript : Oui (recommandé)
- ESLint : Oui
- Tailwind CSS : Oui (recommandé pour la mise en forme mobile)
src/répertoire : Oui- App Router : Oui (recommandé)
- Importation d'un alias : Par défaut (
@/*)
Accédez à votre projet :
cd my-mobile-app
Étape 2 : Configurez Next.js pour l'exportation statique
Capacitor nécessite des fichiers HTML/JS/CSS statiques. Configurez Next.js pour l'exportation statique en mettant à jour 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;
Pourquoi ces paramètres ?
output: 'export'— Génère du HTML statique au lieu de nécessiter un serveur Node.jsimages: { unoptimized: true }— Désactive l'optimisation d'images Next.js (nécessite un serveur)trailingSlash: true— Assure une navigation correcte dans la vue WebView native
Étape 3 : Ajouter les scripts mobiles
Mettez à jour votre package.json avec les scripts de développement 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"
}
}
Testez la construction :
bun run build
Vous devriez voir un out répertoire avec vos fichiers statiques.
Étape 4 : Installer Capacitor 8
Installez les packages de base de Capacitor :
bun add @capacitor/core
bun add -D @capacitor/cli
Installez les plugins essentiels dont la plupart des applications mobiles ont besoin :
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/status-bar @capacitor/preferences
Ce que font ces plugins :
- @capacitor/app — Événements de cycle d'application (avant-plan/arrière-plan, liens profonds)
- @capacitor/clavier — Contrôle du comportement du clavier
- @capacitor/écran de démarrage — Contrôle de l'écran de démarrage natif
- @capacitor/barre de statut — Personnalisez la barre de statut du dispositif
- @capacitor/préférences — Stockage de valeurs clés (comme localStorage mais natif)
Étape 5 : Initialisez Capacitor
Initialisez Capacitor avec vos détails de projet :
bunx cap init "My Mobile App" com.example.mymobileapp --web-dir out
Remplacez :
"My Mobile App"avec votre nom d'affichage d'applicationcom.example.mymobileappavec votre ID d'application (notation de domaine inversé)
Cela crée capacitor.config.ts. Mettez à jour avec la configuration du 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;
Étape 6 : Ajouter les plateformes natives
Installez les packages de plateforme :
bun add @capacitor/ios @capacitor/android
Générez les projets natifs :
bunx cap add ios
bunx cap add android
Cela crée ios et android des dossiers contenant les projets natifs.
Étape 7 : Construire et Exécuter
Construire votre projet et synchroniser avec les plateformes natives :
bun run mobile
Ouvrir dans le simulateur iOS :
bun run mobile:ios
Ou le simulateur Android :
bun run mobile:android
Dans Xcode (iOS) :
- Sélectionnez un simulateur dans le menu des appareils
- Cliquez sur le bouton Play ou appuyez sur
Cmd + R
Dans Android Studio :
- Attendez que Gradle se termine par la synchronisation
- Sélectionnez un simulateur dans le menu des appareils
- Cliquez sur le bouton Exécuter ou appuyez sur
Shift + F10
Étape 8 : Configurer Live Reload
Pour un développement plus rapide, activez la mise à jour en temps réel afin que les modifications apparaissent instantanément sur votre appareil.
- Trouvez votre adresse IP locale :
# macOS
ipconfig getifaddr en0
# Windows
ipconfig
- Créez une configuration de développement Capacitor. Ajoutez à
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;
- Démarrer le serveur de développement et copiez la configuration vers native :
bun run dev &
NODE_ENV=development bunx cap copy
- Rebâtissez dans Xcode/Android Studio
Maintenant, les modifications apportées à votre Next.js code se refléteront automatiquement sur le dispositif.
Étape 9 : Créez votre première écran mobile
Créons une simple page d'accueil mobile-friendly. Mettez à jour 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>
);
}
Étape 10 : Ajoutez un traitement de zone de sécurité
Les appareils mobiles comportent des notches, des indicateurs d'accueil et des barres de statut. Ajoutez un traitement de zone de sécurité avec Tailwind.
Mettez à jour 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;
}
Structure du projet
Votre projet devrait ressembler à ceci :
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
└── ...
Étapes suivantes
Vous disposez maintenant d'une application mobile Next.js fonctionnelle. Voici ce que vous devez faire ensuite :
Configuration essentielle
- Icônes de l'application : Remplacez les icônes par défaut dans
ios/App/App/Assets.xcassetsetandroid/app/src/main/res - Écran d'accueil personnalisé : Personnalisez-le dans les projets natifs ou utilisez
@capacitor/splash-screenconfig - Liens profonds : Configurez les schémas de URL pour votre application
Ajoutez plus de fonctionnalités
- Appareil photo :
bun add @capacitor/camera - Localisation géographique :
bun add @capacitor/geolocation - Notifications Push :
bun add @capacitor/push-notifications - Système de fichiers :
bun add @capacitor/filesystem
Interface utilisateur et transitions natives
Utilisez les plugins Capgo au lieu de Konsta UI pour un sentiment mobile natif :
- @capgo/capacitor-navigation-native — Barre de tab Liquid Glass et navbar native
- @capgo/capacitor-transitions — transitions de page avec un sentiment natif
bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync
Pour les zones de sécurité Tailwind, ajoutez @capgo/tailwind-capacitor:
bun add -D tailwind-capacitor
Voir En utilisant @capgo/capacitor-navigation native, En utilisant @capgo/capacitor-transitions, et le repo tailwind-capacitor pour la configuration spécifique à Next.js.
Résolution des problèmes de mise en page iOS (Vueport, Zone de sécurité, et Débordement horizontal)
Si le contenu semble coupé, décalé ou scrollable horizontalement sur iOS, ajouter plus overflow-x: hidden ou ajuster la balise de vueport seule ne résout généralement pas le problème. Travaillez à travers ces vérifications dans l'ordre.
Assurez-vous que la balise meta de vueport est appliquée correctement
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/insérer la balise meta de viewport pages/_app.tsx, pas _document.tsx.
Gérer l'espace sûr d'iOS à partir d'un seul wrapper racine
Créer un seul coquille d'application et appliquer la mise en forme de l'espace sûr là-bas — et non dans plusieurs composants imbriqués :
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);
}
Envelopper tout le contenu de la page à l'intérieur .app-shellLe recouvrement de l'espace sûr dupliqué dans les en-têtes, les modales et les enveloppes de disposition rend souvent l'interface utilisateur coupée ou trop grande.
Avec @capgo/tailwind-capacitor, vous pouvez exprimer la même mise en forme avec des utilitaires comme pt-safe pb-safe px-safe sur cette coquille seule.
Définir Capacitor iOS contentInset vers never premier
En capacitor.config.ts, préférez un inset natif désactivé et laissez CSS (ou la navigation native) gérer l'espace sûr : contentInsetMode: 'css'Mélanger les inset automatiques de contenu de __CAPGO_KEEP_0__ avec des marges CSS est une cause courante de double espacement.
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-*) L'élément coupable est généralement un élément utilisant
, Tailwind
, une largeur fixe en pixels, ou une large 100vwEn Safari Web Inspector, exécutez : w-screenEn Safari Web Inspector, exécutez : min-width.
En Safari Web Inspector, exécutez :
[...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,
}));
With Tailwind, remplacez w-screen par w-full de nombreux problèmes de débordement horizontal proviennent de 100vw / w-screen, de la duplication de la marge de sécurité de l'espace sûr, ou d'un conteneur de largeur fixe — et non de la balise meta de la vue d'ensemble elle-même.
Mises à jour hors ligne
Configurez Capgo pour envoyer des mises à jour sans résubmission de l'application sur les magasins d'applications :
bunx @capgo/cli init
Résolution de problèmes
Configurez
et essayez à nouveau. bun install Troubleshooting
iOS : « Aucune identité de signature trouvée » Ouvrez Xcode, allez dans Signing & Capabilités, et sélectionnez votre équipe de développement.
Android : « Emplacement de SDK non trouvé »
Créer android/local.properties avec sdk.dir=/path/to/android/sdk
Les modifications ne s'affichent pas sur le dispositif
Assurez-vous d'avoir exécuté bun run mobile après avoir apporté des modifications. Pour le rechargement en direct, vérifiez que l'adresse IP est correcte et que le serveur de développement est en cours d'exécution.
Ressources
- Capacitor 8 Documentation
- Documentation de Next.js 15
- Capgo - Mises à jour en direct
- @capgo/capacitor-navigation-native
- @capgo/capacitor-transitions
- @capgo/tailwind-capacitor
Prêt à envoyer votre application ? Découvrez comment Capgo peut vous aider à livrer des mises à jour plus rapidement — s'inscrire à un compte gratuit aujourd'hui.
Continuez de Build a Next.js Mobile App from Scratch avec Capacitor 8
Si vous utilisez Build a Next.js Mobile App from Scratch avec Capacitor 8 pour planifier l'automatisation de CI/CD, connectez-l’avec Capgo CI/CD pour le flux de travail du produit dans Capgo CI/CD, Capgo Développements natifs pour le flux de travail du produit dans Capgo Développements natifs Capgo Intégrations pour le flux de travail du produit dans Capgo Intégrations Intégration CI/CD pour le détail d'implémentation dans Intégration CI/CD, et GitHub Intégration d'actions pour le détail d'implémentation dans GitHub Intégration d'actions