Dans ce tutoriel, nous allons partir d'une nouvelle React l'application et passer au développement mobile natif avec Capacitor. Vous pouvez aussi ajouter Capgo Native Navigation and Transitions pour un rendu mobile natif, et utiliser tailwind-capacitor pour les safe areas.
Capacitor vous permet de convertir facilement votre application web React en application mobile native, sans modifications majeures et sans devoir apprendre une nouvelle techno 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 maintenant exécuter npm run build sans vous soucier de rien, et vous devriez voir un nouveau dossier out à 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, il faut suivre quelques étapes initiales, mais ensuite, il suffit d'exécuter une seule sync commande.
Tout d'abord, nous pouvons installer le 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 de l'identifiant de bundle.
Ensuite, nous devons installer le package principal ainsi que 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 voir 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 se contentera de compiler votre projet React et d'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 lorsque 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…
Live Reload avec Capacitor
À 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 minimum d'effort !
Activer l'accès à votre application hébergée localement avec le live reload sur votre réseau en faisant en sorte que l'application Capacitor charge le contenu depuis l'URL spécifique.
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
Sous Windows, exécutez :
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 la bonne IP et le bon port, 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 il ne fera que 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 fois de plus 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 il affiche quand même la boîte de dialogue de partage native ! Pour cela, il nous suffit maintenant d’importer le package et d’appeler la share() fonction depuis notre application. Modifions 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 relève du bricolage et en vaut rarement la peine quand vous avez 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 — une navbar native, une barre d'onglets Liquid Glass sur iOS et une barre d'onglets au style flouté sur Android. Votre routeur React conserve l'état des routes ; le plugin gère l'habillage natif.
- @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 du système ; Android utilise un fond 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 le simple ajustement de la balise viewport ne règle généralement pas le problème. Effectuez 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 à l'intérieur <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 d'abord
Dans capacitor.config.ts, préférez désactiver les insets natifs et laissez le CSS (ou la contentInsetMode: 'css') gèrent la safe area :
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'dist',
ios: {
contentInset: 'never',
},
};
Combiner le content inset automatique 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.