Dans ce tutoriel, nous allons partir d'une nouvelle SvelteKit et passer au développement mobile natif avec Capacitor. Vous pouvez également ajouter Capgo Native Navigation and Transitions pour un rendu mobile natif, et utiliser tailwind-capacitor pour gérer les safe areas.
Capacitor vous permet de convertir facilement votre application web SvelteKit en une application mobile native, sans nécessiter de modifications majeures ou d'apprendre un nouveau skill comme React Native.
Suivez ce guide étape par étape pour transformer votre application SvelteKit en application mobile avec Capacitor, avec l'option Capgo pour la navigation native, les transitions et l'aide à la mise en page iOS.
À propos de Capacitor
CapacitorJS change la donne ! Il s'intègre sans effort dans n'importe quel projet web, en enveloppant votre application dans une webview native et en générant pour vous des projets Xcode et Android Studio natifs. Ses plugins permettent d'accéder aux fonctionnalités natives de l'appareil, comme la caméra, via un bridge JavaScript.
Capacitor vous permet de créer une application mobile native fantastique sans configuration complexe ni courbe d'apprentissage abrupte. Son API léger et ses fonctionnalités optimisées facilitent son intégration dans votre projet. Vous serez étonné de la simplicité avec laquelle vous obtiendrez une application native fonctionnelle grâce à Capacitor !
Préparer votre application SvelteKit
Pour créer une nouvelle application SvelteKit, lancez la commande suivante :
npm create svelte@latest my-app
cd my-app
npm install
npm run build
Après avoir exécuté la commande build vous devriez voir un nouveau dist dossier à la racine de votre projet.
Ce dossier sera utilisé plus tard par Capacitor, mais pour l'instant, nous devons le configurer correctement.
Ajouter Capacitor à votre application SvelteKit
Pour packager n'importe quelle application web dans un conteneur mobile natif, nous devons suivre quelques étapes initiales. Ensuite, il suffit de lancer une seule sync commande.
Tout d'abord, installez le Capacitor CLI en tant que dépendance de développement et configurez-le dans votre 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, installez le package core et les packages nécessaires pour les plateformes iOS et Android.
Enfin, ajoutez les plateformes, et Capacitor créera des dossiers pour chaque plateforme à la racine de votre projet :
# Install the Capacitor CLI locally
npm install -D @capacitor/cli
# Initialize Capacitor in your SvelteKit 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 voir de nouveaux ios et et android dossiers dans votre projet SvelteKit.
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 le fichier capacitor.config.ts dans votre projet, qui contient des paramètres Capacitor de base utilisés pendant 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 le fichier capacitor.config.ts et mettez à jour le webDir:
import { CapacitorConfig } from '@capacitor/cli'
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'my-app',
webDir: 'build',
}
export default config
Maintenant que nous avons mis à jour nos paramètres Capacitor, transformons notre projet SvelteKit en application statique en téléchargeant le package d'adaptateur statique approprié :
npm i -D @sveltejs/adapter-static
Une fois le package installé, nous devrons modifier le svelte.config.js pour passer de l'auto-adaptateur au mode statique :
import adapter from '@sveltejs/adapter-static'
import { vitePreprocess } from '@sveltejs/kit/vite'
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter({
// default options are shown. On some platforms
// these options are set automatically — see below
pages: 'build',
assets: 'build',
fallback: null,
precompress: false,
strict: true
})
}
}
export default config
Avec le svelte.config.js mis à jour, nous devrons ajouter une prerender option en créant une +layout.js page pour src/routes et ajoutez simplement l'export suivant à +layout.js:
export const prerender = true
Après avoir ajouté et mis à jour la +layout.js page, nous devrons ajouter nos plateformes mobiles et recompiler notre projet pour créer le build dossier
Vous pouvez le faire en exécutant les commandes suivantes :
npm run build
npx cap sync
La première commande npm run build va compiler votre projet SvelteKit et copier le build statique, tandis que la seconde commande npx cap sync va synchroniser tous les code web vers les bons emplacements des plateformes natives afin qu'ils puissent s'afficher dans une app.
De plus, la commande sync peut mettre à jour les plateformes natives et installer des plugins, donc lorsque vous installez de nouveaux Plugins Capacitor, il est temps de lancer npx cap sync à nouveau.
Sans vous en rendre compte, vous avez terminé le processus. 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 au programme Apple Developer 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 un jeu d'enfant. Dans Android Studio, il vous suffit d'attendre que tout soit prêt pour déployer votre application sur un appareil connecté sans modifier aucun 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 guidera tout au long du processus (mais là encore, vous devez être inscrit au Developer Program). Ensuite, il vous suffit d'appuyer 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 SvelteKit sur un appareil mobile. Voici un exemple :
Mais attendez, il existe aussi un moyen plus rapide de le faire pendant le développement…
Live Reload 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 !
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'application Capacitor 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
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: 'dist',
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, comme illustré dans l'exemple ci-dessus.
Maintenant, nous pouvons appliquer ces changements en les copiant dans notre projet natif :
npx cap copy
Le copy la commande est similaire à sync, mais elle ne fera que copier les modifications apportées au dossier web et la configuration, sans mettre à jour le projet natif.
Vous pouvez désormais déployer votre application une dernière fois via Android Studio ou Xcode. Ensuite, si vous modifiez quelque chose dans votre application Svelte, l'application se rechargera automatiquement et affichera les modifications !
Gardez à l'esprit que si vous installez de nouveaux plugins comme la caméra, un rebuild de votre projet natif reste 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 SvelteKit par défaut à des fins de démonstration.
Utiliser des plugins Capacitor
Voyons comment utiliser un plugin Capacitor en action, comme nous l'avons mentionné précédemment. Pour ce faire, nous pouvons installer un plugin simple en exécutant :
npm i @capacitor/share
Il n'y a rien de sorcier dans le Plugin de partage, mais cela ouvre 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 donc le src/routes/index.svelte comme ceci :
<script>
import { Share } from '@capacitor/share';
async function share() {
await Share.share({
title: 'Open Youtube',
text: 'Check new video on youtube',
url: 'https://www.youtube.com',
dialogTitle: 'Share with friends'
});
}
</script>
<h1>Welcome to SvelteKit and Capacitor!</h1>
<button on:click={share}>Share now!</button>
Comme mentionné précédemment, lors de l'installation de nouveaux plugins, nous devons effectuer une synchronisation puis redéployer l'application sur notre appareil. Pour ce faire, lancez la commande suivante :
npx cap sync
Une fois le bouton pressé, vous pourrez admirer le superbe dialogue de partage natif en action !
Ensuite, vous pouvez rendre l'application plus native sur iOS et Android grâce à la navigation et aux 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 native avec Capgo Native Navigation et Transitions
Je travaille depuis des années avec Ionic pour compiler des applications multiplateformes, mais l'intégrer à SvelteKit est laborieux et rarement rentable si vous utilisez déjà Tailwind CSS.
Pour un rendu mobile natif dans une application SvelteKit + 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 routeur SvelteKit gère l'état des routes ; le plugin gère l'interface native.
- @capgo/capacitor-transitions — transitions de page de style Ionic et retour par balayage (edge swipe) sur iOS dans la couche WebView, sans adopter l'UI d'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 fond de 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 }) => {
goto(`/${id}`);
});
Ajoutez des transitions de page natives dans votre app shell :
<script>
import { goto } from '$app/navigation';
import { routerOutlet, page, setDirection } from '@capgo/capacitor-transitions/svelte';
import '@capgo/capacitor-transitions';
function openSettings() {
setDirection('forward');
goto('/settings');
}
</script>
<cap-router-outlet use:routerOutlet>
<cap-page use:page>
<cap-content slot="content">
<slot />
</cap-content>
</cap-page>
</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 la navigation. Ne dupliquez pas les headers ou footers web lorsque la navigation native gère déjà ces surfaces.
Consultez les guides complets : Utiliser @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é sur tailwind-capacitor sur npm). Il permet de fournir safe-areas utilitaires et autres plugins Tailwind compatibles avec Capacitor :
bun add -D tailwind-capacitor
Dans src/app.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 les saupoudrer env(safe-area-inset-*) manuellement. Le projet est activement développé — s'il manque quelque chose à votre configuration SvelteKit, ouvrez une PR sur GitHub.
Corriger les problèmes de mise en page iOS (viewport, safe area et overflow horizontal)
Si le contenu semble coupé, décalé ou s'il défile horizontalement sur iOS, ajoutez plus de overflow-x: hidden ou ajuster seulement la balise viewport ne résout généralement pas le problème. Passez ces vérifications en revue dans l'ordre.
Assurez-vous que la balise meta viewport est correctement appliquée
Dans src/app.html, configurez la balise meta viewport dans <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 le padding de la safe area à cet endroit — et non dans plusieurs composants imbriqués :
html,
body,
body {
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. La duplication du padding safe-area dans les headers, les modales et les wrappers de layout donne souvent l'impression que l'UI est tronquée ou trop grande.
Avec @capgo/tailwind-capacitor, vous pouvez appliquer le même padding avec des utilitaires comme pt-safe pb-safe px-safe sur ce shell unique.
Configurez Capacitor iOS contentInset à never en premier
Dans capacitor.config.ts, préférez l'inset natif désactivé et laissez le CSS (ou celui de Native Navigation contentInsetMode: 'css') gérer la safe area :
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'build',
ios: {
contentInset: 'never',
},
};
Mélanger l'inset de contenu automatique de Capacitor avec le CSS env(safe-area-inset-*) le padding est une cause fréquente de double espacement.
Identifiez l'élément réel qui déborde
Le coupable habituel est un élément utilisant 100vw, Tailwind w-screen, une largeur fixe en pixels, ou un large min-width.
Dans Safari Web Inspector, 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 avec w-full quand c'est possible. De nombreux problèmes de débordement horizontal proviennent de 100vw / w-screen, un padding safe-area dupliqué ou un conteneur à largeur fixe — et non pas 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 aient toujours accès aux dernières fonctionnalités et corrections de bugs.
Si vous souhaitez apprendre à ajouter Capgo à votre application SvelteKit, consultez l'article suivant :
Learn how Capgo can help you build better apps faster, créez un compte gratuit today.
Continuer : Créer des applications mobiles avec SvelteKit et Capacitor
Si vous utilisez Créer des applications mobiles avec SvelteKit et Capacitor pour planifier l'automatisation CI/CD, le relier à CI/CD Capgo pour le workflow produit dans le CI/CD de Capgo, Capgo Native Build pour le workflow produit dans les Capgo Native Builds, Intégrations Capgo pour le workflow produit dans les intégrations Capgo, Intégration CI/CD pour les détails d'implémentation de l'intégration CI/CD, et Intégration GitHub Actions pour les détails d'implémentation de l'intégration GitHub Actions.