Dans ce tutoriel, nous allons partir d'une nouvelle React app React pour passer au développement mobile natif avec Capacitor. Vous pouvez aussi ajouter Capgo Native Navigation and Transitions pour un rendu natif, et utiliser tailwind-capacitor pour gérer les safe areas.
Capacitor vous permet de convertir facilement votre application web React en une app mobile native, sans modifications majeures ni apprentissage d'un nouveau skill comme React Native.
En quelques étapes simples, la plupart des applications React peuvent être transformées en applications mobiles.
Ce tutoriel vous guide tout au long du processus : on part d'une nouvelle application React, puis on intègre Capacitor pour basculer dans l'univers des applications mobiles natives. Vous pouvez aussi utiliser Capgo Native Navigation, Transitions, et tailwind-capacitor pour les safe areas.
À propos de Capacitor
CapacitorJS change la donne ! Vous pouvez l'intégrer sans effort dans n'importe quel projet web : il encapsule votre application dans une webview native et génère pour vous les projets natifs Xcode et Android Studio. En plus, ses plugins donnent accès aux fonctionnalités natives de l'appareil, comme la caméra, via un pont JS.
Avec Capacitor, vous obtenez une excellente application mobile native sans configuration complexe ni courbe d'apprentissage raide. Son API léger et ses fonctionnalités épurées le rendent très facile à intégrer à votre projet. Croyez-moi, vous serez surpris de la facilité avec laquelle on obtient une application native pleinement fonctionnelle avec Capacitor !
Préparer votre application React
Il existe plusieurs façons de créer une application React, mais dans ce tutoriel, nous allons utiliser la plus simple, qui génère une application React vide :
npx create-react-app my-app
Pour créer une application mobile native, il nous faut un exporter de notre projet. Ajoutons donc un script simple dans notre package.json qui servira à builder et exporter le projet React :
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
}
Vous pouvez désormais exécuter npm run build sans aucune crainte, et vous devriez voir un dossier out tout neuf à la racine de votre projet.
Ce dossier sera utilisé par Capacitor par la suite, mais pour l'instant, nous devons le configurer correctement.
Ajouter Capacitor à votre application React
Pour packager n'importe quelle application web dans un conteneur mobile natif, nous devons suivre quelques étapes initiales, mais ensuite, il suffit d'exécuter une seule sync commande.
Tout d'abord, nous pouvons installer Capacitor CLI en tant que dépendance de développement, puis le configurer dans notre projet. Lors de la configuration, vous pouvez appuyer sur « entrée » pour accepter les valeurs par défaut du nom et du bundle ID.
Ensuite, nous devons installer le package core et les packages correspondants pour les plateformes iOS et Android.
Enfin, nous pouvons ajouter les plateformes, et Capacitor créera des dossiers pour chaque plateforme à la racine de notre projet :
# Install the Capacitor CLI locally
npm install -D @capacitor/cli
# Initialize Capacitor in your React project
npx cap init
# Install the required packages
npm install @capacitor/core @capacitor/ios @capacitor/android
# Add the native platforms
npx cap add ios
npx cap add android
À ce stade, vous devriez pouvoir observer de nouveaux iOS et Android dossiers de votre projet React.
Ce sont de véritables projets natifs !
Pour accéder au projet Android plus tard, vous devez installer Android Studio. Pour iOS, vous avez besoin d'un Mac et devez installer Xcode.
De plus, vous devriez trouver un fichier capacitor.config.ts dans votre projet, qui contient des paramètres Capacitor fondamentaux utilisés lors de la synchronisation. La seule chose à laquelle vous devez prêter attention est le webDir, qui doit pointer vers le résultat de votre commande de build. Actuellement, il est incorrect.
Pour corriger cela, ouvrez le fichier capacitor.config.json et mettez à jour le webDir:
{
"appId": "com.example.app",
"appName": "my-app",
"webDir": "out",
"bundledWebRuntime": false
}
Vous pouvez tester en exécutant les commandes suivantes :
npm run build
npx cap sync
La première commande npm run build va simplement compiler votre projet React et exporter le build statique.
Tandis que la deuxième commande npx cap sync synchronisera tous les code web vers les emplacements appropriés des plateformes natives afin qu'ils puissent être affichés dans une application.
De plus, la commande sync peut mettre à jour les plateformes natives et installer des plugins, donc quand vous installez un nouveau Plugins Capacitor il est temps de lancer npx cap sync à nouveau.
Sans même vous en rendre compte, vous avez terminé. Voyons maintenant l'application sur un appareil !
Compiler et déployer des apps natives
Pour développer des apps iOS, vous devez avoir Xcode installé, et pour les apps Android, vous devez avoir Android Studio installé. De plus, si vous prévoyez de distribuer votre app sur les stores, vous devez vous inscrire à l'Apple Developer Program pour iOS et à la Google Play Console pour Android.
Si vous débutez dans le développement mobile natif, vous pouvez utiliser le Capacitor CLI pour ouvrir facilement les deux projets natifs :
npx cap open ios
npx cap open android
Une fois vos projets natifs configurés, déployer votre application sur un appareil connecté est simple. Dans Android Studio, il vous suffit d'attendre que tout soit prêt pour déployer votre application sur un appareil connecté sans changer le moindre paramètre. Voici un exemple :

Dans Xcode, vous devez configurer votre compte de signature pour déployer votre application sur un appareil réel plutôt que sur le simulateur. Si vous ne l'avez jamais fait, Xcode vous guide tout au long du processus (mais là encore, vous devez être inscrit au Developer Program). Ensuite, il vous suffit de cliquer sur play pour lancer l'application sur votre appareil connecté, que vous pouvez sélectionner en haut. Voici un exemple :

Félicitations ! Vous avez déployé avec succès votre application web React sur un appareil mobile. Voici un exemple :
Mais attendez, il existe aussi un moyen plus rapide de faire cela pendant le développement…
Capacitor Live Reload
À ce stade, vous avez probablement l'habitude du hot reload avec tous les frameworks modernes, et la bonne nouvelle est que vous pouvez bénéficier de la même fonctionnalité sur un appareil mobile avec un effort minimal !
Activez l'accès à votre application hébergée localement avec le live reload sur votre réseau en faisant charger le contenu de l’URL spécifique par l’application Capacitor.
La première étape consiste à trouver votre adresse IP locale. Si vous utilisez un Mac, vous pouvez la trouver en exécutant la commande suivante dans le terminal :
ipconfig getifaddr en0
Sur Windows, lancez :
ipconfig
Cherchez ensuite l'adresse IPv4.
Nous pouvons demander à Capacitor de charger l'application directement depuis le serveur en ajoutant une autre entrée à notre capacitor.config.ts fichier :
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'my-app',
webDir: 'out',
bundledWebRuntime: false,
server: {
url: 'http://192.168.x.xx:3000',
cleartext: true
}
};
export default config;
Assurez-vous d'utiliser l'IP et le port corrects, j'ai utilisé le port React par défaut dans cet exemple.
Maintenant, nous pouvons appliquer ces changements en les copiant dans notre projet natif :
npx cap copy
Le copy la commande est similaire à sync, mais cela va seulement copier les modifications apportées au dossier web et la configuration, sans mettre à jour le projet natif.
Vous pouvez maintenant déployer votre application une dernière fois via Android Studio ou Xcode. Ensuite, si vous modifiez quelque chose dans votre application React, l'application se rechargera automatiquement et affichera les changements !
Gardez à l'esprit que si vous installez de nouveaux plugins comme la caméra, un nouveau build de votre projet natif sera nécessaire. En effet, les fichiers natifs sont modifiés et cela ne peut pas se faire à la volée.
Notez que vous devez utiliser l'IP et le port corrects dans votre configuration. Le bloc code ci-dessus affiche le port React par défaut à des fins de démonstration.
Utiliser les plugins Capacitor
Voyons comment utiliser un plugin Capacitor en pratique, que nous avons déjà évoqué plusieurs fois. Pour cela, nous pouvons installer un plugin assez simple en exécutant :
npm i @capacitor/share
Il n'y a rien de sorcier dans le plugin Share, mais cela affiche quand même la boîte de dialogue de partage native ! Pour cela, il suffit désormais d'importer le package et d'appeler la share() fonction depuis notre application. Changeons le src/App.js comme ceci :
import React from 'react';
import { Share } from '@capacitor/share';
function App() {
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>
<h1>Welcome to React and Capacitor!</h1>
<p>
<h2>Cool channel</h2>
<button onClick={() => share()}>Share now!</button>
</p>
</div>
);
}
export default App;
Comme mentionné plus haut, quand on installe de nouveaux plugins, il faut faire une sync puis redéployer l'application sur notre appareil. Pour cela, lancez la commande suivante :
npx cap sync
Une fois le bouton cliqué, vous pourrez voir le superbe dialogue de partage natif en action !
Ensuite, vous pouvez rendre l'application plus native sur iOS et Android avec la navigation et les transitions Capgo, et corriger les problèmes de mise en page iOS courants qui causent des débordements horizontaux ou des safe areas rognées.
Une interface fluide avec Capgo Native Navigation et Transitions
J'ai travaillé pendant des années avec Ionic pour compiler des applications multiplateformes, mais l'intégrer à React est laborieux et rarement rentable si vous utilisez déjà Tailwind CSS.
Pour un rendu mobile natif dans une application React + Capacitor, utilisez les plugins Capgo plutôt que des kits UI web comme Konsta UI :
- @capgo/capacitor-native-navigation — navbar native, barre d'onglets Liquid Glass sur iOS et style de barre d'onglets floutée sur Android. Votre React router gère l'état des routes ; le plugin gère l'interface native.
- @capgo/capacitor-transitions — des transitions de page façon Ionic et le swipe-back depuis le bord sur iOS dans la couche WebView, sans adopter l'UI Ionic.
Installez les deux :
bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync
Configurez la navigation native avec le mode CSS inset pour que le contenu web respecte les barres natives :
import { NativeNavigation } from '@capgo/capacitor-native-navigation';
await NativeNavigation.configure({
contentInsetMode: 'css',
animationDuration: 360,
glass: {
effect: 'liquidGlass',
},
});
Affichez une barre d'onglets Liquid Glass (iOS utilise le rendu système ; Android utilise un arrière-plan WebView flouté) :
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 }) => {
navigate(`/${id}`);
});
Ajoutez des transitions de page natives dans votre app shell :
import { useEffect, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import '@capgo/capacitor-transitions';
import { initTransitions, setDirection, setupRouterOutlet } from '@capgo/capacitor-transitions/react';
initTransitions({ platform: 'auto' });
export function AppShell() {
const navigate = useNavigate();
const outletRef = useRef<HTMLElement>(null);
useEffect(() => {
if (outletRef.current) {
setupRouterOutlet(outletRef.current, { platform: 'auto', swipeGesture: 'auto' });
}
}, []);
const openSettings = () => {
setDirection('forward');
navigate('/settings');
};
return <cap-router-outlet ref={outletRef}>{/* routes */}</cap-router-outlet>;
}
Enveloppez les pages routées dans cap-router-outlet, cap-page, et cap-content, et appelez setDirection('forward') ou setDirection('back') avant de naviguer. Ne dupliquez pas les headers ou footers web lorsque la navigation native gère ces surfaces.
Consultez les guides complets : Utilisation de @capgo/capacitor-native-navigation et Utiliser @capgo/capacitor-transitions.
Safe areas avec Tailwind
Pour les safe areas de l'appareil avec Tailwind CSS, utilisez @capgo/tailwind-capacitor (publié sous tailwind-capacitor sur npm). Il fournit safe-areas utilitaires et d'autres plugins Tailwind compatibles Capacitor :
bun add -D tailwind-capacitor
Dans src/index.css:
@import 'tailwindcss';
@plugin "@capgo/tailwind-capacitor/platform";
@plugin "@capgo/tailwind-capacitor/safe-areas";
Utilisez des utilitaires tels que pt-safe, pb-safe, et px-safe au lieu de parsemer env(safe-area-inset-*) à la main. Le projet est activement développé — s'il manque quelque chose pour votre configuration React, ouvrez une PR sur GitHub.
Corriger les problèmes de mise en page iOS (viewport, zone sécurisée et débordement horizontal)
Si le contenu semble coupé, décalé ou défile horizontalement sur iOS, ajouter plus de overflow-x: hidden ou si le simple ajustement de la balise viewport ne suffit pas, suivez ces vérifications dans l'ordre.
Assurez-vous que la balise meta viewport est correctement appliquée
Ajoutez la balise meta viewport dans index.html inside <head>:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
Gérez la safe area iOS depuis un seul wrapper racine
Créez un shell d'application unique et appliquez-y le padding de la safe area — pas dans plusieurs composants imbriqués :
html,
body,
#root {
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);
}
Enveloppez tout le contenu de la page dans .app-shell. Un padding de safe area dupliqué dans les headers, les modales et les wrappers de layout donne souvent l'impression que l'UI est rognée ou trop grande.
Avec @capgo/tailwind-capacitor, vous pouvez obtenir le même padding avec des utilitaires comme pt-safe pb-safe px-safe sur ce shell unique.
Configurez Capacitor iOS contentInset vers never premièrement
Dans capacitor.config.ts, préférez désactiver le native inset et laissez le CSS (ou la navigation native contentInsetMode: 'css') gérer la safe area :
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'dist',
ios: {
contentInset: 'never',
},
};
Mélanger l'automatic content inset de Capacitor avec le CSS env(safe-area-inset-*) le padding est une cause fréquente de double espacement.
Trouvez l'élément qui déborde réellement
Le coupable habituel est un élément utilisant 100vw, Tailwind w-screen, une largeur fixe en pixels, ou un grand min-width.
Dans le Web Inspector de Safari, lancez :
[...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,
}));
Avec Tailwind, remplacez w-screen par w-full dès que possible. De nombreux problèmes de débordement horizontal proviennent de 100vw / w-screen, d'un padding safe-area dupliqué, ou d'un conteneur à largeur fixe — et non de la balise meta viewport elle-même.
Conclusion
Capacitor est une excellente option pour créer des applications natives à partir d'un projet web existant, offrant un moyen simple de partager code et de maintenir une interface cohérente.
Et avec l'ajout de Capgo, il est encore plus facile d'ajouter des live updates à votre application, garantissant que vos utilisateurs bénéficient toujours des dernières fonctionnalités et corrections de bugs.
Si vous souhaitez apprendre à ajouter Capgo à votre application React, consultez l'article suivant :
Poursuivre avec « Créer des applications mobiles avec React et Capacitor »
Si vous utilisez Créer des applications mobiles avec React et Capacitor pour planifier l'automatisation CI/CD, et le connecter avec CI/CD Capgo pour le workflow produit dans le CI/CD de Capgo, Capgo Native Build pour le workflow produit dans les Native Builds de Capgo, Intégrations Capgo pour le workflow produit dans les intégrations de Capgo, Intégration CI/CD pour le détail d'implémentation dans l'intégration CI/CD, et Intégration GitHub Actions pour les détails d'implémentation de l'intégration GitHub Actions.