# Deploy project 3 (React|Heroku) ## Pré-requis - avoir `git init`ialisé son projet (à la racine) - avoir un dossier CRA nommé `client/` - avoir vérifié que `client/.git` n'existe pas (sinon le `rm -rf client/.git`) ## Steps 1. Créer son app sur Heroku (par ex `myapp`) : https://dashboard.heroku.com/ 2. Ajouter le remote `heroku` (pour pouvoir `git push heroku master`) : ```sh $ heroku login $ heroku git:remote -a myapp ``` :::info :point_right: Vérifiez par un `git remote -v` que le remote `heroku` apparait bien ::: 3. dans le `package.json` **de la racine** : ```json "scripts:": { ... "build": "cd client && npm install && npm run build" } ``` :::info :point_right: Ce script sera exécuté par coté Heroku juste après avoir `git push heroku master` le code ::: :::success On peut nous-même l'essayer en local : ```sh $ npm run build $ ls client/build ``` ::: cf. https://devcenter.heroku.com/articles/nodejs-support#customizing-the-build-process 4. dans `app.js` (du serveur), **après les routes**: ```javascript // Serve static files from client/build folder app.use(express.static('client/build')); // For any other routes: serve client/build/index.html SPA app.use((req, res, next) => { res.sendFile(`${__dirname}/client/build/index.html`, err => { if (err) next(err) }) }); ``` :::info Explications: notre serveur va jouer 2 roles : servir les datas JSON de la DB + héberger le dossier `build` (de notre SPA React buildée dedans) Quand une requête lui arrive et qu'aucune ne matche avec nos routes d'API : - on va alors tenter de servir un fichier de notre dossier `build/` - si aucun fichier ne matche, on sert en dernier fallback la SPA (`index.html`) ::: :::danger ☝🏻 Faîtes attention de ne pas avoir de route `GET /` de définie dans Express, autrement votre SPA ne sera pas servie sur `/`. ::: 5. ajouter une variable shell `REACT_APP_APIURL` à la commande `"start"` du `client/package.json`: ```json "scripts": { "start": "REACT_APP_APIURL=http://localhost:5000 react-scripts start", ... } ``` Dans votre application React, vous pourrez l'utiliser pour vos requêtes axios, par ex : ```jsx // client/src/App.js axios.get(`${process.env.REACT_APP_APIURL || ""}/profile`) ``` :::warning :point_up: En production, `process.env.REACT_APP_APIURL` ne sera pas définie. En effet, client et serveur seront hébergés sur le même domaine.