Catégories
JavaScript

Next.js

logo Next.js

NextJs est un framework Javascript Reactjs qui popularise le SSR (Server Side Rendering) Javascript de par sa facilité de prise en main (tuto officiel très clean).

Ce qui rend l’usage de Next.js intuitif, réside dans le fait le routage est une correspondance entre un fichier JavaScript et une URL, c’est à dire:
le fichier /pages/toto.js générera automatiquement l’URL http://monsite/toto.

  • Avec sa version 7 (19/09/18), le Framework Javascript Next.js qui permet de faire du SSR avec React, inclus des mises à jour Webpack 4 et Babel 7, ce qui le remet au goût du jour
  • La version 9 (08/07/19), voit apparaître les API Routes mais surtout les Dynamic Routes (appelés aussi URL Slugs ou Pretty/Clean URLs)

Avantages

Les intérêts de cette solution:

  • SSR out of the box
  • learning curve très raide pour les développeurs React! une prise en main rapide grâce à leurs tuto
  • utilise un routage par page très intuitif
  • utilise Webpack 4 et son HMR, qui permet de développer et de voir ses modification appliquées quasi instantanément dans le navigateur, sans perdre le state des composants
  • système de plugins officiels intéressants (SEO, offline, Webworkers etc.) et aussi d’autres (ssr routage dynamique) a trouver sur Github

Routing

Une URL est crée automatiquement dès qu’on dépose un fichier JS ou JSX dans le dossier /pages/ (par convention ce dossier doit s’appeler pages).
Next nécessite que le fichier JavaScript contienne un export de composant React pour pouvoir effectuer son rendu.
Pour les éléments statiques (images, css et autres) il existe également un dossier /static/ réservé a cet effet.

Navigation

La navigation est simplifiée par l’usage de composants Nextjs Link et Router auxquels on peut associer l’objet URL.

<Link as={`/route-a-afficher/${show.id}`} href={`/route-correspondant-fichier?id=${show.id}`}>
  • la prop href permet au framework de faire le lien entre l’URL et les fichiers JS contenu dans le dossier pages
  • la prop as permet de créer et d’afficher dans le HTML résultant un href alias (ici le lien pointera vers /p/xxx), qu’il faudra traiter coté back (méthode render de l’API next).

Le HOC withRouter permet de récupérer dans nos composants, via les props du composant React (props.router):

  • les informations de routage (voir l’API)
  • des méthodes de pushState, replaceState et beforePopState

Cycle de vie du Router

Le Router de Next.js propose un ensemble d’évènements qu’il est possible d’écouter :

  • routeChangeStart(url)
  • routeChangeComplete(url)
  • routeChangeError(err, url)
  • beforeHistoryChange(url)
  • hashChangeStart(url)
  • hashChangeComplete(url)

Server Side Rendering

Dans la plupart des cas, des routes simples ne suffiront pas, et on aura des URL qui ne vont plus correspondre à des fichiers présents dans /pages, comme par exemple lorsqu’on utilise les props « as » du composant <Link/>.
Il est alors nécessaire d’utiliser un routage coté serveur, voici un exemple en Node/Express (selon doc):

const next = require('next')
const app = next({ dev })
const handle = app.getRequestHandler()

app
  .prepare()
  .then(() => {
    const server = express()
    server.get("/produits?/:univers/:category*?", (req, res) => {
      const actualPage = "/produits"
      const queryParams = { ...req.params }
      app.render(req, res, actualPage, queryParams)
    });
....

Appels Ajax

Si on suit le tuto de Next.js, on s’aperçoit qu’ils utilisent la librairie unfetch (très légère) et son compagnon isomorphic-unfetch, mais on peut bien sure utiliser des librairies plus connues comme isomorphic-fetch ou disposant de plus de fonctionnalités comme Axios (permet d’annuler les requêtes Ajax).

la méthode getInitialProps

Avec Next.js, on utilise la méthode statique getInitialProps qui permet comme son nom l’indique, de charger les props du composant avec le résultat de la requête Ajax. Il est possible d’utiliser cette méthode de 2 façons:

  • soit dans un composant React (qui possède donc un lifecyle), en définissant cette méthode: static async getInitialProps({ req }) {….
  • soit en définissant un lifecycle methode pris en charge par le framework Nexjs, pour un composant stateless (ici nommé MaPage): MaPage.getInitialProps = async ({ req }) => {

propriétés de l’objet context

La méthode getInitialProps reçoit en paramètre un objet context  (paramètre req dans les 2 ex ci-dessus) qui contient les informations de routage:

  • pathname – chemin next (correspondant au fichier js)
  • asPath – URL complète telle que visible dans le navigateur incluant la query string
  • queryquery string de l’URL parsé dans un objet
  • req – objet request HTTP (serveur uniquement)
  • res – objet response HTTP (serveur uniquement)
  • jsonPageRes – objet Fetch Response (client uniquement)
  • err – objet Error si une erreur intervient lors du render

Styling

CSS avec styled-jsx

Nextjs a fait le choix d’utiliser une des solution CSS-in-JS, styled-jsx parmi les nombreuses solutions existantes, qui permet d’avoir des styles scopés au niveau du composant, et surtout d’appliquer les styles lors du rendu coté serveur.
Les styles ne se propagent pas aux composants enfants par défaut, mais il est possible de forcer la propagation en utilisant l’attribut global.
Styled-jsx est traité dans Nextjs par un plugin Babel styled-jsx/babel.

L’utilisation est encore une fois très intuitive, car il suffit d’écrire ses styles directement dans des balises <style jsx>  à l’intérieur de ses composants en utilisant la syntaxe template strings:

<style jsx>{`
    h1, a {
    font-family: "Arial";
  }
`}</style>

CSS classique

La doc Next.js recommande d’utiliser styled-jsx pour le styling, mais il est tout à fait possible d’importer du CSS, SASS, LESS ou Stylus grâce à des plugins Next.

De plus si on souhaite utiliser une bibliothèque CSS, styled-jsx va automatiquement prefixer les noms de classe dans le HTML rendu, ce créera des interférences.
On peut éviter cela en utilisant l’attribut optionCLassName au lieu du classique class.

<Select optionClassName="react-select" />

Squelettes de projets NextJS

Un outil sympathique, qui fourni un squelette de projet Nextjs/React/Redux est create-next-app, parfait pour voir rapidement les branchements entre ces outils 🙂

Concernant Material UI, il y a un exemple de projet Nexjs/MaterialUI ainsi qu’une doc SSR Material UI.