Skip to content

ginko.luclu7.fr

Ginko est le nom du réseau de transport en commun de l'agglomération de Besançon. En guise d'exercice, j'ai décidé de recréer une application web (mobile-first) permettant de visualiser les horaires des bus et des trams de ce réseau.

Il est disponible à l'adresse ginko.luclu7.fr.

Technologies utilisées

J'ai utilisé le framework Next.js v14 pour développer cette application. Next.js est un framework basé sur React, qui facilite la création d'applications web. Ce projet utilise le nouvel App Router, avec les React Server Components. Cela permet d'appeler l'API de Ginko directement depuis le serveur, et de ne pas exposer la clé API côté client.

Pour le style, j'ai également utilisé Tailwind CSS pour le design de l'application.

Réalisation

Suspense

J'ai pu découvrir Suspense, le mécanisme de React pour gérer les chargements asynchrones. Cela m'a permis d'afficher un écran de chargement (un skelette) pendant le chargement des données.

Récupération des données

La récupération des données (data fetching en anglais) est souvent un sujet délicat.

Dans Next.js, dans un composant serveur, la fonction fetch est légèrement différente de celle de base: elle intègre un cache. Il permet de configurer l'expiration des données, et de les recharger si nécessaire.

Par exemple, ici, je récupère des données, et je les mets en cache pendant 30 secondes:

javascript
fetch(`https://api/endpoint`, {next: {revalidate: 30}})

Si un nouvel appel sur le même endpoint est effectué, et que 30 secondes se sont écoulées depuis le dernier appel, les données sont rechargées et l'API re-appelée. Cela permet de ne pas surcharger l'API, et cela simplifie la gestion des données.

Une autre alternative aurait été d'utiliser un Store avec Redux, mais cela aurait été plus complexe à mettre en place. Cependant, Redux Query, une fois mis en place, est très simple et agréable à utiliser.

Pages statiques et dynamiques

Next.js propose trois types de pages différents:

  • Les pages statiques (SSG), générées à la construction du site et mises en cache
  • Les pages entièrement dynamique (SSR), générées à chaque appel
  • Les pages hybrides (ISR)

Ce dernier cas est le plus intéressant: pour une page dont le contenu ne change que toutes les 24h par exemple, on peut la générer statiquement, et la mettre en cache. Cela permet de ne pas surcharger le serveur, et de ne pas attendre le chargement des données. Cela s'appelle l'Incremental Static Regeneration, ISR.

Dans cette application, j'ai utilisé les trois types de pages, pour les différentes parties de l'application. Next.js choisit automatiquement le meilleur type de page à utiliser.

Il y a quatre pages hybrides dans cette application:

  • La page d'accueil, qui affiche les lignes avec une disruption
  • La page des lignes, qui affiche les lignes (et leur statut)
  • La page des tarifs, qui affiche les tarifs des différents abonnements et tickets (rafrachis tous les 24h)

Par exemple, la page des horaires d'un arrêt n'est pas mise en cache, car elle est appelée très fréquemment, et les données changent souvent. Le nombre d'arrêt est également très élevé, et il n'est pas possible de les mettre en cache.

Thème sombre automatique

J'ai également ajouté un thème sombre automatique, qui s'adapte à la préférence de l'utilisateur.

Grâce à Tailwind CSS, il suffit d'ajouter le préfix dark: à une classe pour qu'elle ne s'applique qu'en thème sombre. Par exemple, dark:bg-slate-900. Cela permet de gérer le thème sombre facilement.

Ce code ne s'applique donc que si le thème sombre est activé par le navigateur.

Recherche dans la liste des arrêts

Une chose très simple à implémenter dans une application web cliente est la recherche: il suffit de filtrer les données en fonction de la recherche de l'utilisateur.

Cependant, la liste des arrêts est un composant serveur. Il n'est donc pas possible d'effectuer une recherche côté client, car les données ne sont pas disponibles. J'ai donc dû implémenter une recherche côté serveur, en passant la recherche en paramètre de l'URL.

exemple de recherche

Hébergement

L'application est hébergée dans le cloud PaaS de Vercel, qui est le créateur de Next.js. Il aurait totalement été possible de l'héberger moi-même, mais cela me permet d'essayé Vercel, et de voir ce que cela donne.

À chaque commit publié sur GitHub, Vercel reconstruit l'application, et la déploie automatiquement. Cela permet de ne pas avoir à gérer les déploiements manuellement, et de ne pas avoir à gérer un serveur.

Conclusion

Ce projet m'a permis de découvrir Next.js, et de voir comment il est possible de créer des applications web modernes, avec des technologies récentes. Je connaissais déjà Tailwind mais ce projet a été un très bon exercice pour le maîtriser davantage.

Prochaines étapes

Je compte ajouter une fonctionnalité de favoris, qui permettra de sauvegarder des arrêts pour les retrouver plus facilement. J'ai le choix entre utiliser le Local Storage, ou une base de données côté serveur. J'ai également l'idée d'ajouter le support d'une PWA, pour permettre l'installation de l'application sur le téléphone.

Captures d'écran

Page d'accueil Page d'accueil

Page des lignes Liste des lignes, avec leur état (normal, perturbé, etc.)

Exemple d'une ligne Détail d'une ligne, avec les arrêts desservis et une carte

Horaires d'un arrêt Horaires d'un arrêt, avec les prochains passages