FAQ Next === Next.js cheatsheet === __Le code du composant page est appelé à la fois sur le serveur et le client?__ C'est le fonctionnement des pages en Next qui sont [pré rendus](https://nextjs.org/docs/basic-features/pages#pre-rendering). Ce sont des composants React très particulier. Ils sont appelés une première fois côté serveur Node, afin d'obtenir un HTML. Ils utilisent pour cela une API React, [React DOM Server](https://reactjs.org/docs/react-dom-server.html). Ce HTML est envoyé au browser. Cela permet un affichage le plus rapide (TTFB) et permet d'améliorer le SEO. Ensuite, le JS est appelé une 2ème fois par le client, cela s'appelle [l'hydratation](https://reactjs.org/docs/react-dom.html#hydrate). Dans ce cas, React respecte le HTML déjà présent dans la page et ajoute ses traitements. Il est nécessaire que le code soit compatible entre ce qui est généré par le serveur et ce que le client est censé trouver (nom des classes CSS, etc..). La génération HTML ne prend pas en compte les useEffect sur la page. En conséquence : - un composant classique React, peut appeler une API SessionStorage, car ce composant sera lancé côté browser. - une page (bien qu'aussi un composant React), ne pourra pas appeler cette API, puisqu'elle sera d'abord executée côté serveur. __Console.log ne marche pas côté serveur quand je fais yarn build + yarn start ?__ Maintenant ça marche... __Comment utiliser des variables d'environnement qui marche aussi bien en SSR qu'en CSR ?__ La problématique est de pouvoir utiliser une variable `API_URL`, différente entre la production et le développement, et qui fonctionne dans les 2 modes en routing serveur (`SSR`) ou en routing client (`CSR`). On suppose donc que la page en question a bien besoin d'être accessible en SSR et CSR, ce qui n'est pas toujours le cas. Mais si le cas se présente, cela revient à utiliser `getInitialProps` dans la page Next. En SSR, on récupére une page HTML déjà hydratée. C'est le serveur web qui renvoie cette page. Étant un process Node, il peut utiliser `process.env.API_URL` pour savoir quelle URL utiliser. En revanche, pour le CSR, c'est le composant React qui est envoyé au browser. C'est le browser qui est en charge de faire appel à l'API. Or, un browser n'a pas accès à process.env. Une solution est d'utiliser un fichier `.env` non versionné dans Git, et qui contient la bonne valeur pour cet environnement (en prod, mettre l'API_URL de prod, en staging, celle de staging, etc.). __Détail de la solution__ `.env` ``` API_URL=http://localhost:3000 ``` `/pages/MyPage.js` ```jsx MyPage.getInitialProps = ctx => { await fetch(process.env.API_URL + LOGIN_ENDPOINT, () => { ... }) } ``` `next.config.js` ```js require("dotenv").config() const withCSS = require("@zeit/next-css") module.exports = withCSS({}) module.exports = { env: { API_URL: process.env.API_URL, }, } ``` Quand on lance `yarn dev`, ou bien `yarn build` + `yarn start`, webpack et Next, vont remplacer la valeur de toutes les occurents de `process.env.API_URL` par la valeur trouvée dans `.env`. Le remplacement sera alors bien effectué suivant les valeurs trouvées dans `.env`. Référence: https://github.com/zeit/next.js#exposing-configuration-to-the-server--client-side __Est-ce que getInitialProps est indispensable?__ Non, getInitialProps est un outil puissant qui permet de récupérer des données aussi bien dans un mode CSR que SSR. En CSR, c'est le navigateur qui appelle directement l'API et qui récupére un flux JSON, qui servira à hydrater un composant React qui est déjà récupéré par le serveur Next. En SSR, en revanche, le navigateur appelle une page du serveur Next, qui lui renvoie une page HTML déjà hydratée. Pour cela, c'est le serveur Next qui va appeler lui même l'API. La différence se voit bien avec les Dev Tools. En mode CSR, on voit l'appel à l'API. En SSR, on ne voit que l'appel au serveur Web. __Console.log in Next.js__ Utiliser `console.log` dans Next.js va ajouter une ligne de log soit dans la console du browser, soit dans le terminal qui a lancé `yarn dev`. En particulier, si la page se charge à partir du serveur, c'est à dire en chargeant une URL dans le champ du navigateur ou bien en appuyant sur le bouton Refresh/Cmd-R du navigateur, tout le log apparaîtra dans le terminal. Les transitions qui viendront ensuite, qui arrivent en cliquant avec la souris, vont déclencher des logs qui arriveront dans le browser. À garder en tête si l'on est supris à un moment qu'il manque une ligne de log. __Comment ajouter du code devant être executé uniquement sur le serveur ou uniquement sur le client?__ L'objet window est disponible uniquement pour un browser. Donc pour mettre du code uniquement serveur, on écrit : ```js if (typeof window === 'undefined') { // code serveur } ``` ```js if (typeof window !== 'undefined') { // code client } ``` __Quelles sont les différences entre la version de développement et la version de production?__ La version de dev permet le hot reload et possède les sources maps. La version de production ne les a pas. De plus, les pages qui n'ont pas de `getInitialProps` sont générés statiquement et seront donc rendus plus rapidement. __Comment installer rapidement un exemple?__ See https://github.com/zeit/next.js/tree/canary/examples `yarn create next-app --example with-jest with-jest-app cd with-jest-app yarn test` - Babel sert à transpiler pour Node les tests écrits en ES6 (avec les imports au lieu des require, etc..) __Comment styler le CSS en Next?__ See https://github.com/zeit/styled-jsx#constants Utiliser `<style jsx>` pour styler à la CSS un composant en étanchéité. Seuls les balises HTML du composant peuvent être stylées, pas les composants enfants du composant courant. Si l'on veut styler un composant enfant (par exemple pour styler un composant qu'on n'a pas écrit, p. ex. le composant Markdown), on peut utiliser des styles globaux. ```<style jsx global>{`...``` Attention: ces styles s'appliqueront aussi bien aux composants enfants, qu'aux autres composants si les sélecteurs CSS s'appliquent.