Mode d'emploi — de zĂ©ro Ă  publiĂ©

Application mobile

Une app iOS + Android Ă  partir de ton backend Next.js existant, avec React Native + Expo. Ce n'est pas un projet Ă  part — c'est une couche en plus sur ce que tu as dĂ©jĂ .

Sommaire
01Initialiser le projet Expo
02Exposer le backend en API
03Authentification mobile — Better Auth
04Style — NativeWind
05Écrans & fonctionnalitĂ©s
06Build & publication — EAS
RĂšgle du jeu : tu tapes chaque commande toi-mĂȘme dans ton terminal, dans l'ordre. Tu ne passes Ă  l'Ă©tape suivante que quand la case « vĂ©rification » est cochĂ©e. Si une commande plante, copie-colle l'erreur exacte — on corrige ensemble, tu ne devines pas.

PrĂ©requis important : ce guide part du principe que tu as dĂ©jĂ  un projet Next.js avec Prisma/Supabase et Better Auth en place (voir les autres guides). L'app mobile ne recrĂ©e pas de backend — elle appelle celui qui existe dĂ©jĂ .

Réutilisable vs spécifique : les étapes réutilisable sont valables pour n'importe quelle app mobile de ta stack. Les étapes spécifique dépendent du produit que tu construis.
📖 C'est quoi chaque techno (Expo, React Native, NativeWind...) ? Le lexique complet est sur la page d'accueil →
01
Réutilisable

Initialiser le projet Expo

Une app qui démarre sur ton téléphone via Expo Go, dans un dossier séparé du projet web.

Prérequis : Node.js et pnpm installés. L'app Expo Go installée sur ton téléphone (App Store / Play Store).

  1. Crée le projet Expo, à cÎté de ton projet web
    npx create-expo-app@latest mon-app-mobile --template default
    cd mon-app-mobile
    C'est un dĂ©pĂŽt sĂ©parĂ© du projet Next.js — le mobile et le web restent deux applications distinctes qui parlent Ă  la mĂȘme base de donnĂ©es via l'API.
    👁 Comment voir le rĂ©sultat : tape ls dans mon-app-mobile — app/, package.json doivent exister.
  2. Initialise Git
    git init
    git add -A
    git commit -m "chore: init projet Expo"
    👁 Comment voir le rĂ©sultat : tape git log --oneline — une ligne avec ton message de commit doit s'afficher.
  3. Lance le serveur de développement
    npx expo start
    Un QR code s'affiche dans le terminal. Scanne-le avec l'appareil photo (iOS) ou l'app Expo Go (Android) pour ouvrir l'app sur ton téléphone, en direct.
    👁 Comment voir le rĂ©sultat : l'app s'ouvre sur ton tĂ©lĂ©phone avec l'Ă©cran par dĂ©faut d'Expo. Modifie un texte dans app/index.tsx, enregistre — le changement doit apparaĂźtre sur le tĂ©lĂ©phone en 1-2 secondes, sans rĂ©installer l'app (hot reload).
Vérification
02
Réutilisable

Exposer le backend en API

Ton app mobile peut appeler ton backend Next.js par HTTP, comme n'importe quel client.

Prérequis : le projet Next.js existe déjà (Prisma + Supabase branché).

  1. Comprends la différence clé
    Les Server Actions (utilisĂ©es dans le web) ne sont appelables que depuis une page Next.js du mĂȘme projet — pas depuis une app mobile. Il faut donc des Route Handlers classiques : des vraies routes API avec une URL, comme une API REST.
  2. Dans ton projet Next.js (pas le projet Expo), crée le dossier et le fichier de la route
    mkdir -p app/api/produits && touch app/api/produits/route.tsNew-Item -ItemType Directory -Force -Path app/api/produits; New-Item -ItemType File -Force -Path app/api/produits/route.ts
  3. Colle le contenu de la route API
    // app/api/produits/route.ts
    import { prisma } from "@/lib/db/client";
    
    export async function GET() {
      const produits = await prisma.produit.findMany();
      return Response.json(produits);
    }
    Chaque donnĂ©e dont l'app mobile a besoin doit avoir sa route sous app/api/.... C'est le mĂȘme Prisma, la mĂȘme base — juste exposĂ©e diffĂ©remment.
  4. Autorise les requĂȘtes venant de l'app mobile (CORS)
    Par dĂ©faut, Next.js n'accepte que les requĂȘtes venant de son propre domaine. Ajoute les en-tĂȘtes CORS nĂ©cessaires dans la route, ou un middleware, pour autoriser ton app mobile Ă  appeler l'API en dĂ©veloppement comme en production.
  5. Teste la route depuis un navigateur ou curl
    curl http://localhost:3000/api/produitsInvoke-RestMethod http://localhost:3000/api/produits
    👁 Comment voir le rĂ©sultat : le terminal doit afficher du JSON (ex. [{"id":"...","nom":"..."}]), pas une page d'erreur HTML. Teste ensuite depuis l'app mobile (sur le mĂȘme Wi-Fi que ton ordinateur, avec l'IP locale au lieu de localhost) pour confirmer que la requĂȘte aboutit aussi depuis le tĂ©lĂ©phone.
Vérification
03
Réutilisable

Authentification mobile — Better Auth

Se connecter depuis le téléphone, avec la session gérée en toute sécurité.

Prérequis : Better Auth déjà configuré cÎté serveur Next.js.

  1. Installe le client Better Auth pour Expo
    npx expo install @better-auth/expo expo-secure-store
    Better Auth fournit un client pensĂ© pour React Native — il gĂšre les appels rĂ©seau vers ton serveur d'auth existant.
    👁 Comment voir le rĂ©sultat : @better-auth/expo apparaĂźt dans package.json.
  2. Crée le fichier du client auth
    touch lib/auth-client.tsNew-Item -ItemType File -Force -Path lib/auth-client.ts
    // lib/auth-client.ts
    import { createAuthClient } from "better-auth/react";
    import { expoClient } from "@better-auth/expo/client";
    import * as SecureStore from "expo-secure-store";
    
    export const authClient = createAuthClient({
      baseURL: "http://TON-IP-LOCALE:3000",
      plugins: [
        expoClient({
          scheme: "monappmobile",
          storagePrefix: "monappmobile",
          storage: SecureStore,
        }),
      ],
    });
    Contrairement au web (cookies), le mobile stocke le token dans expo-secure-store — un espace chiffrĂ© du tĂ©lĂ©phone, pas dans une simple variable ou un fichier en clair. Remplace TON-IP-LOCALE par l'IP locale de ton ordinateur (pas localhost, qui sur un tĂ©lĂ©phone pointerait vers le tĂ©lĂ©phone lui-mĂȘme) ; en production tu pointeras vers ton URL Vercel (Ă©tape 6).
  3. Crée les fichiers des écrans connexion / inscription
    touch app/login.tsx app/signup.tsxNew-Item -ItemType File -Force -Path app/login.tsx, app/signup.tsx
  4. Colle le contenu de l'écran de connexion
    // app/login.tsx
    import { useState } from "react";
    import { View, TextInput, Button, Text } from "react-native";
    import { router } from "expo-router";
    import { authClient } from "@/lib/auth-client";
    
    export default function LoginScreen() {
      const [email, setEmail] = useState("");
      const [password, setPassword] = useState("");
      const [error, setError] = useState("");
    
      async function handleLogin() {
        const { error } = await authClient.signIn.email({ email, password });
        if (error) return setError(error.message ?? "Connexion refusée");
        router.replace("/");
      }
    
      return (
        <View className="flex-1 justify-center p-6 gap-3">
          <TextInput placeholder="Email" value={email} onChangeText={setEmail} autoCapitalize="none" className="border p-3 rounded" />
          <TextInput placeholder="Mot de passe" value={password} onChangeText={setPassword} secureTextEntry className="border p-3 rounded" />
          {error ? <Text className="text-red-500">{error}</Text> : null}
          <Button title="Se connecter" onPress={handleLogin} />
        </View>
      );
    }
    Duplique la mĂȘme structure pour app/signup.tsx (fonction SignupScreen) en remplaçant authClient.signIn.email(...) par authClient.signUp.email({ email, password, name: email }).
    👁 Comment voir le rĂ©sultat : sur ton tĂ©lĂ©phone, crĂ©e un compte test depuis l'Ă©cran d'inscription — puis vĂ©rifie dans Prisma Studio (cĂŽtĂ© projet web) qu'une ligne apparaĂźt dans la table User. Reconnecte-toi ensuite depuis l'Ă©cran de connexion avec les mĂȘmes identifiants.
  5. Colle le contenu du fichier app/_layout.tsx pour protéger les écrans
    // app/_layout.tsx
    import { Redirect, Slot } from "expo-router";
    import { authClient } from "@/lib/auth-client";
    
    export default function RootLayout() {
      const { data: session, isPending } = authClient.useSession();
      if (isPending) return null;
      if (!session) return <Redirect href="/login" />;
      return <Slot />;
    }
    Ce fichier existe dĂ©jĂ  (créé par create-expo-app) — remplace son contenu. Il s'applique Ă  tous les Ă©crans : vĂ©rifie la session au lancement de l'app et redirige vers l'Ă©cran de connexion si elle est absente ou expirĂ©e.
    👁 Comment voir le rĂ©sultat : ferme complĂštement l'app puis rouvre-la — tu dois rester connectĂ© (pas de retour Ă  l'Ă©cran de connexion). DĂ©connecte-toi : tu dois ĂȘtre redirigĂ© vers l'Ă©cran de connexion, et rouvrir l'app ne doit plus te reconnecter automatiquement.
Vérification
04
Réutilisable

Style — NativeWind

Les mĂȘmes classes Tailwind que sur le web, appliquĂ©es Ă  des composants React Native.

Prérequis : étape 1 validée.

  1. Installe NativeWind
    npx expo install nativewind tailwindcss
    Tailwind CSS n'existe pas nativement en React Native (pas de navigateur, pas de vrai CSS) — NativeWind traduit les classes Tailwind en styles React Native au moment de la compilation.
  2. Configure Tailwind pour le projet mobile
    npx tailwindcss init
    Un tailwind.config.js propre au projet mobile — les fichiers scannĂ©s ne sont pas les mĂȘmes que cĂŽtĂ© web (App.tsx, app/**/*.tsx au lieu de app/ Next.js).
    👁 Comment voir le rĂ©sultat : ls tailwind.config.js — le fichier doit exister.
  3. Utilise les classes directement dans les composants
    // exemple
    <View className="flex-1 items-center justify-center bg-white">
      <Text className="text-lg font-bold">Bonjour</Text>
    </View>
    👁 Comment voir le rĂ©sultat : ouvre app/index.tsx (l'Ă©cran d'accueil créé automatiquement Ă  l'Ă©tape 1), remplace le JSX retournĂ© par cet exemple, enregistre — sur ton tĂ©lĂ©phone, le texte « Bonjour » doit s'afficher centrĂ©, en gras, sur fond blanc. Change bg-white en bg-red-500 pour confirmer que les classes prennent bien effet.
  4. Déclare tes couleurs une seule fois, dans tailwind.config.js
    // tailwind.config.js
    module.exports = {
      content: ["./app/**/*.{js,jsx,ts,tsx}", "./components/**/*.{js,jsx,ts,tsx}"],
      theme: {
        extend: {
          colors: {
            primary: "#2563eb",
            background: "#ffffff",
          },
        },
      },
    };
    Sans ça, tu retapes le mĂȘme code couleur (#2563eb) dans chaque Ă©cran — si tu veux changer de teinte plus tard, tu dois le faire une seule fois ici, plutĂŽt que de chasser chaque occurrence dans tous les fichiers.
    👁 Comment voir le rĂ©sultat : remplace bg-red-500 par bg-primary et text-lg reste, sauvegarde — le fond doit prendre la couleur bleue dĂ©clarĂ©e dans primary.
  5. Pour modifier le style plus tard
    Garde npx expo start lancĂ© en continu — c'est le rechargement Ă  chaud (« Fast Refresh ») : tu ouvres l'Ă©cran concernĂ© (dans app/), tu changes les classes dans className, tu sauvegardes, l'app se met Ă  jour seule sur le tĂ©lĂ©phone sans recompiler. Pour changer une couleur partout d'un coup, retouche tailwind.config.js plutĂŽt que chaque Ă©cran un par un. Pour savoir ce que fait une classe (p-4, rounded-lg, text-xl...), consulte le lexique ou tailwindcss.com/docs.
Vérification
05
Spécifique au projet

Écrans & fonctionnalitĂ©s

Le cƓur mĂ©tier de l'app — ce qui change Ă  chaque projet.

Prérequis : étapes 2 et 3 validées.

  1. Mets en place la navigation entre écrans
    npx expo install expo-router
    Expo Router fonctionne par dossiers, comme l'App Router de Next.js — un fichier = un Ă©cran. Le repĂšre est le mĂȘme que celui que tu connais dĂ©jĂ  cĂŽtĂ© web.
    👁 Comment voir le rĂ©sultat : crĂ©e un deuxiĂšme Ă©cran (ex. app/profil.tsx) et un lien vers lui — tape dessus sur ton tĂ©lĂ©phone, tu dois naviguer vers le nouvel Ă©cran avec l'animation de transition native.
  2. Crée le fichier d'un écran qui appelle ta route API
    touch app/produits.tsxNew-Item -ItemType File -Force -Path app/produits.tsx
  3. Colle le contenu de l'écran
    // app/produits.tsx
    import { useEffect, useState } from "react";
    import { View, Text, FlatList } from "react-native";
    
    type Produit = { id: string; nom: string };
    
    export default function ProduitsScreen() {
      const [produits, setProduits] = useState<Produit[]>([]);
    
      useEffect(() => {
        fetch("http://TON-IP-LOCALE:3000/api/produits")
          .then((r) => r.json())
          .then(setProduits);
      }, []);
    
      return (
        <FlatList
          data={produits}
          keyExtractor={(p) => p.id}
          renderItem={({ item }) => (
            <View className="p-4 border-b">
              <Text>{item.nom}</Text>
            </View>
          )}
        />
      );
    }
    MĂȘme logique que cĂŽtĂ© web (rĂ©cupĂ©rer des donnĂ©es, les afficher, les valider avec Zod avant envoi cĂŽtĂ© formulaire) — seuls les composants d'affichage changent. En production, remplace l'URL par ton domaine Vercel (Ă©tape 6).
    👁 Comment voir le rĂ©sultat : ouvre l'Ă©cran produits sur ton tĂ©lĂ©phone — les vraies donnĂ©es de ta base (créées via Prisma Studio ou l'app web) doivent s'afficher, pas des donnĂ©es factices codĂ©es en dur.
  4. GĂšre les notifications push si le projet en a besoin
    npx expo install expo-notifications
    Uniquement si le produit en a l'usage (ex. prĂ©venir un utilisateur) — ne l'ajoute pas par dĂ©faut.
Vérification
06
Réutilisable

Build & publication — EAS

Une app installable, publiée sur l'App Store et le Play Store.

Prérequis : compte Expo (expo.dev), compte développeur Apple et Google si publication réelle visée.

  1. Installe l'outil de build EAS
    npm install -g eas-cli
    eas login
    👁 Comment voir le rĂ©sultat : tape eas whoami — ton nom de compte Expo doit s'afficher.
  2. Configure le projet pour le build
    eas build:configure
    👁 Comment voir le rĂ©sultat : un fichier eas.json apparaĂźt Ă  la racine du projet.
  3. Renseigne les variables d'environnement de prod
    eas secret:create --name API_URL --value https://tondomaine.vercel.app
    L'app mobile en production doit appeler ton backend Next.js déployé, pas localhost.
    👁 Comment voir le rĂ©sultat : eas secret:list doit afficher API_URL dans la liste.
  4. Lance un build de test
    eas build --platform android --profile preview
    Un build « preview » s'installe directement sur un tĂ©lĂ©phone pour tester, sans passer par les stores — plus rapide qu'un cycle de validation complet.
    👁 Comment voir le rĂ©sultat : une fois le build terminĂ© (~10-20 min, suivi sur expo.dev), un lien de tĂ©lĂ©chargement .apk s'affiche dans le terminal — installe-le sur un tĂ©lĂ©phone Android, l'app doit se lancer et appeler ton API de production.
  5. Soumets aux stores quand tu es prĂȘt
    eas build --platform all --profile production
    eas submit --platform all
    La validation Apple prend en général quelques jours ; celle de Google est plus rapide. Prévois cette marge avant une date de lancement.
    👁 Comment voir le rĂ©sultat : le statut de la soumission est visible sur App Store Connect et Google Play Console — il passe de « En cours d'examen » Ă  « ApprouvĂ© » (ou un refus avec le motif, Ă  corriger).
Vérification