Aller au contenu
Me contacter
Tous les articles
Mis à jour le 5 min de lecture

Refonte de l’e-commerce Cora avec Next.js et le SSR

Pour Cora, groupe belge de la grande distribution, nous avons réalisé la refonte du front-end de la boutique en ligne en Next.js, sur une API existante, avec un rendu côté serveur par magasin, deux langues et des parcours alignés sur les applications mobiles. J’y ai surtout porté l’espace client.

  • Next.js
  • SSR
  • Performance
  • E-commerce

Cora est un groupe belge de la grande distribution. Chez Ikomobi, nous avons réalisé la refonte du front-end de sa boutique en ligne en Next.js, en conservant l’API existante. L’équipe réunissait un lead dev, deux développeurs fullstack et un intégrateur, avec un chef de projet et un designer ; chacun a touché à l’ensemble du projet, et j’ai pour ma part surtout porté l’espace client. Voici les choix qui ont structuré ce travail.

Le point de départ

Le site web précédent datait de plusieurs années, mais Cora disposait déjà d’applications iOS et Android, développées par les équipes mobiles d’Ikomobi. Elles servaient de référence, et le web devait en reprendre à l’identique les parcours, des formulaires au tunnel d’achat en passant par la logique métier.

Le front ne gérait aucune donnée lui-même. Tout transitait par une API existante qui évoluait peu, avec laquelle il fallait composer telle quelle, structure et temps de réponse compris.

Le site devait enfin gérer plusieurs magasins aux configurations différentes (click & collect, livraison, services), en français comme en néerlandais.

Pourquoi du SSR plutôt que des pages statiques ?

Sur ce site, presque tout dépend du magasin choisi par le client, qu’il s’agisse de l’accès à l’e-shop, de l’offre, des services ou d’une partie des contenus éditoriaux. Ce choix, mémorisé dans un cookie, est relu à chaque requête. Une page catalogue ou une fiche produit existe donc en autant de versions qu’il y a de magasins.

Générer ces pages à l’avance, en statique ou en ISR, aurait obligé à produire et à invalider une version par magasin et par langue, pour un contenu qui varie selon le visiteur. Le rendu côté serveur à chaque requête, avec l’App Router de Next.js, était à la fois plus simple et plus juste. La page arrive complète, construite pour le magasin du client, sans effet « sapin de Noël » où les blocs s’allument les uns après les autres, ni squelettes de chargement en attendant les données. Elle reste en outre indexable par les moteurs de recherche.

Les contenus éditoriaux proviennent d’un CMS headless, Prismic, qui dispose d’un espace principal et d’un espace par magasin. Chaque magasin gère ainsi ses propres contenus dans le CMS.

Comment travailler avec une API qu’on ne peut pas modifier ?

La première difficulté tenait à la session. L’API exige un token à chaque appel, et celui d’un client connecté expire avant d’être rafraîchi. Si plusieurs appels partent en même temps avec un token expiré, il faut ne le rafraîchir qu’une fois, puis rejouer les autres. En voici le principe, réécrit de façon générique :

// Per user session: calls that fail on an expired token wait for a single
// refresh, then replay. The pending refresh is never shared between users.
async function withFreshToken(session, request) {
  try {
    return await request(session.token);
  } catch (error) {
    if (error.status !== 401) throw error;
    session.refreshing ??= refreshToken(session).finally(() => (session.refreshing = null));
    await session.refreshing;
    return request(session.token);
  }
}

La seconde concernait les temps de chargement. Certaines pages, ainsi que le layout commun à toutes, attendaient environ 4 secondes d’appels à l’API avant de s’afficher. Faute de pouvoir modifier l’API, tout se jouait côté front, où trois leviers les ont ramenés sous la seconde :

  • lancer en parallèle les appels indépendants, jusque-là enchaînés ;
  • charger les données une seule fois au niveau du layout et les transmettre en props aux composants qui en ont besoin, au lieu que chacun refasse son propre appel ;
  • conserver en cookie ou en session les informations stables, comme le magasin choisi ou la session, pour ne plus les redemander à chaque page.

Nous n’avons pas, en revanche, mis en cache les réponses de l’API. Ce choix a été arrêté avec l’équipe technique, car la question se pose tout autrement sur le web et dans les applications mobiles.

L’espace client, ma partie principale

J’ai surtout développé ce que le client voit une fois identifié :

  • l’authentification, avec l’inscription, la connexion et le mot de passe oublié ;
  • le profil, qui regroupe les informations personnelles, le foyer, les centres d’intérêt, les préférences et les adresses ;
  • la carte de fidélité, que l’on crée ou associe à son compte, et sa cagnotte ;
  • les réductions et bons de réduction liés à la fidélité ;
  • la gestion des magasins, du premier choix au changement en cours de navigation.

Ces écrans sont pour l’essentiel des formulaires, validés avec Formik et Yup et protégés des robots par reCAPTCHA. Pour la recherche de magasins et d’adresses, j’ai également géré les clés des services Google (Maps) sur Google Cloud Platform.

Comment garder le web cohérent avec les applications mobiles ?

Le web reprenait les parcours des applications mobiles, maquettés par les designers. À l’inverse, certaines pages du site s’affichent directement dans les applications, en webview, avec une session propre à l’application, et le CMS propose des blocs de contenu réservés aux applications.

L’équipe produit pilotait les décisions UX, y compris un peu d’A/B testing sur certaines pages comme le catalogue ou les promotions. Il me revenait de les développer fidèlement, sans alourdir les temps de chargement.

Même lorsque l’API est gérée par un prestataire externe, un front-end bien structuré peut beaucoup. Ici, il a permis un rendu adapté à chaque magasin, des chargements nettement réduits là où ils pesaient le plus et un espace client complet, cohérent avec les applications mobiles. L’interface est visible sur la fiche du projet Cora, et la modernisation de SRS raconte un autre exemple de pages accélérées côté front. Pour en discuter, écrivez-moi.