Offline-first Progressive Web App for identifying sugarcane diseases, built for CIRAD.
D-CAS 2.0 (Détermination et Catalogue des Affections de la canne à Sucre) is a trilingual (EN / FR / ES) field tool that helps agronomists and growers identify sugarcane diseases through a guided questionnaire or a searchable catalog of referenced pathologies.
- Guided diagnosis — Answer a few questions about observed symptoms to narrow down possible diseases.
- Disease catalog — Browse, search and sort all referenced diseases with their pathogens, symptoms, images and geographical distribution.
- Fully offline — Once loaded, the app works without connectivity thanks to a Service Worker that caches the identification key and disease images.
- Trilingual — Interface and content available in English, French and Spanish, with per-language disease trees.
- Mobile-friendly — Responsive layout optimized for both portrait and landscape phone usage in the field.
- About / Legal / Privacy pages — Informational pages accessible from the navigation menu.
- PWA installable — Can be installed on mobile and desktop devices.
| Concern | Choice |
|---|---|
| Language | TypeScript (strict mode) |
| Bundler | Vite 5 |
| Styling | Tailwind CSS 4 + PostCSS |
| i18n | i18next + browser detector |
| Routing | Custom client-side router (src/router.ts) |
| Offline | Native Service Worker (public/sw.js) |
| Framework | None — vanilla DOM manipulation |
- Node.js ≥ 18
- npm ≥ 9
git clone git@github.com:ffillouxdev/D-CAS-2.0.git
cd D-CAS-2.0
npm installnpm run devThe dev server starts on http://localhost:5173.
npm run build # Type-check with tsc, then bundle to dist/
npm run preview # Preview the production build locallyD-CAS-2.0/
├── public/
│ ├── assets/ # Static images (logos, backgrounds, CTA)
│ ├── datas/ # Identification keys + disease images (gitignored)
│ └── sw.js # Service Worker
├── src/
│ ├── components/ # Reusable UI pieces (header, questionnaire, ...)
│ ├── data/ # Data loaders (key-loader.ts)
│ ├── views/ # Page-level views (home, catalog, about, privacy, legal)
│ ├── i18n.ts # Translation resources & language detection
│ ├── layout.ts # Shared layout exports
│ ├── router.ts # Client-side router
│ ├── main.ts # Entry point
│ └── style.css # Tailwind directives
├── index.html
├── tailwind.config.js
├── vite.config.ts
└── tsconfig.json
The public/datas/ folder is gitignored and must be provided separately by CIRAD. It contains:
identification-key.json— English disease tree (primary source)cle-identification.json— French disease treeclave-de-identificacion.json— Spanish disease treediseases-img-webp/— Disease photographs in WebP format (confidential, CIRAD property, ~350 Mo)
The loader (src/data/key-loader.ts) falls back to the English key when a translated key is empty.
| Check | Tool |
|---|---|
| Type-check & build | GitHub Actions |
| npm audit (critical) | GitHub Actions |
| Code quality | SonarCloud |
Production server: Red Hat Enterprise Linux 9, served by Nginx.
# Build
npm run build
# Deploy dist/ to server
rsync -avz dist/ root@croult.cirad.fr:/usr/share/nginx/website_canedr/
# Deploy data (keys + images) — first time or when updated
rsync -avz /tmp/datas-deploy/ root@croult.cirad.fr:/usr/share/nginx/website_canedr/datas/HTTP security headers (CSP, HSTS, nosniff, etc.) are defined in
deploy/nginx-security-headers.conf.
Copy it to /etc/nginx/snippets/ on the server and include it in the
server block (see instructions in the file), then nginx -t && systemctl reload nginx.
Based on the book A Guide to Sugarcane Diseases, edited by Philippe Rott, Jean-Claude Girard and Jean Heinrich Daugrois, published by Éditions Quæ.
Proprietary — © CIRAD. All rights reserved. Disease content and images are the property of CIRAD and contributing photographers.
Developed by ffillouxdev for CIRAD.