# 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.