Dans ce tutoriel, nous allons partir d'une nouvelle SvelteKit 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 SvelteKit en une application mobile native, sans modifications majeures ni apprentissage d'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'optimisation du layout 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 surpris de la simplicité avec laquelle vous pouvez obtenir 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. Pendant la configuration, vous pouvez appuyer sur « Entrée » pour accepter les valeurs par défaut pour le nom et le 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 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 fichier 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 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 dans +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 compilera votre projet SvelteKit et copiera 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 de nouveaux Plugins Capacitor, il est temps d'exécuter 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 à 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 SvelteKit sur un appareil mobile. Voici un exemple :
Mais attendez, il existe aussi un moyen plus rapide de le faire 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 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
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 la bonne IP et le bon port, 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 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 Svelte, 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 indique le port SvelteKit par défaut à des fins de démonstration.
Utiliser les plugins Capacitor
Voyons concrètement comment utiliser un plugin Capacitor, que nous avons déjà évoqué plusieurs fois. Pour cela, nous pouvons installer un plugin simple en exécutant :
npm i @capacitor/share
Il n'y a rien de sorcier dans le plugin Share, mais cela affiche le dialogue de partage natif ! 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é 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 à SvelteKit reste bricolé et rarement rentable quand vous avez déjà Tailwind CSS.
Pour un rendu mobile natif dans une application SvelteKit + Capacitor, utilisez des plugins Capgo plutôt que des kits UI uniquement web comme Konsta UI :
- @capgo/capacitor-native-navigation — une navbar native, une barre d'onglets Liquid Glass sur iOS et un style de barre d'onglets floutée sur Android. Votre routeur SvelteKit conserve l'état des routes ; le plugin gère le chrome 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 }) => {
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 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/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 parsemer env(safe-area-inset-*) à la main. Le projet est activement développé — s'il manque quelque chose pour votre configuration SvelteKit, 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
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-y le padding de la safe area — pas 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. 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: 'build',
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 SvelteKit, consultez l'article suivant :
Learn how Capgo can help you build better apps faster, créez un compte gratuit today.
Continuer la lecture : Créer des applications mobiles avec SvelteKit et Capacitor
Si vous utilisez Développer des applications mobiles avec SvelteKit 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.