diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/DaoHibernate.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/DaoHibernate.java
index dc1e1b7898b45a82adbc06d4e1f9f69c8da4eb3c..d35b0b9976a7e4305b879ed567e6b9bea8f1601d 100644
--- a/www-server/src/main/java/fr/agrometinfo/www/server/dao/DaoHibernate.java
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/DaoHibernate.java
@@ -12,6 +12,10 @@ import org.hibernate.engine.spi.SessionImplementor;
 import jakarta.persistence.NoResultException;
 import jakarta.persistence.Query;
 import jakarta.persistence.TypedQuery;
+import jakarta.persistence.criteria.CriteriaBuilder;
+import jakarta.persistence.criteria.CriteriaQuery;
+import jakarta.persistence.criteria.Order;
+import jakarta.persistence.criteria.Root;
 import lombok.extern.log4j.Log4j2;
 
 /**
@@ -104,10 +108,34 @@ public abstract class DaoHibernate<T> {
     /**
      * @return all entities for the related class
      */
-    public final List<T> findAll() {
+    public List<T> findAll() {
+        LOGGER.traceEntry();
+        return findAll(null);
+    }
+
+    /**
+     * @param orders column → asc/desc
+     * @return all entities for the related class
+     */
+    public final List<T> findAll(final Map<String, String> orders) {
         LOGGER.traceEntry();
         try (ScopedEntityManager em = getScopedEntityManager()) {
-            final TypedQuery<T> query = em.createQuery("SELECT t FROM " + clazz.getName() + " t", clazz);
+            final CriteriaBuilder cBuilder = em.getCriteriaBuilder();
+            final CriteriaQuery<T> cQuery = cBuilder.createQuery(clazz);
+            final Root<T> root = cQuery.from(clazz);
+            cQuery.select(root);
+            if (orders != null) {
+                final List<Order> orderList = new ArrayList<>();
+                orders.forEach((column, asc) -> {
+                    if ("DESC".equalsIgnoreCase(asc)) {
+                        orderList.add(cBuilder.desc(root.get(column)));
+                    } else {
+                        orderList.add(cBuilder.asc(root.get(column)));
+                    }
+                });
+                cQuery.orderBy(orderList);
+            }
+            final TypedQuery<T> query = em.createQuery(cQuery);
             LOGGER.traceExit();
             return query.getResultList();
         } catch (final NoResultException e) {
diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/RegionDaoHibernate.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/RegionDaoHibernate.java
index 0e64c2bd7d5fb2f9e6fce25c435a67b6226fb7c4..b72980cef53a7b5ee848c16ff6dd80d9912e1428 100644
--- a/www-server/src/main/java/fr/agrometinfo/www/server/dao/RegionDaoHibernate.java
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/RegionDaoHibernate.java
@@ -1,5 +1,8 @@
 package fr.agrometinfo.www.server.dao;
 
+import java.util.List;
+import java.util.Map;
+
 import fr.agrometinfo.www.server.model.Region;
 import jakarta.enterprise.context.ApplicationScoped;
 
@@ -23,4 +26,9 @@ public class RegionDaoHibernate extends DaoHibernate<Region> implements RegionDa
         return super.find(id);
     }
 
+    @Override
+    public final List<Region> findAll() {
+        return super.findAll(Map.of("name", "asc"));
+    }
+
 }
diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java b/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java
index bdfd30b316933cb7a63175c9cb27cb3c20c3a41b..fdcfce02c4f870874e69b49c5c9916b08733b2da 100644
--- a/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java
@@ -5,13 +5,12 @@ import static fr.agrometinfo.www.server.util.GeometryUtils.toFeature;
 import java.time.LocalDate;
 import java.time.ZoneId;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 import org.geojson.Feature;
 import org.geojson.FeatureCollection;
@@ -175,7 +174,7 @@ public class IndicatorResource implements IndicatorService {
         LOGGER.traceEntry();
         final var locale = LocaleUtils.getLocale(httpServletRequest);
         final var indicators = praDailyValueDao.findIndicators();
-        final Map<Long, PeriodDTO> dtos = new HashMap<>();
+        final Map<Long, PeriodDTO> dtos = new LinkedHashMap<>();
         for (final Indicator indicator : indicators) {
             final var p = indicator.getPeriod();
             final var key = Long.valueOf(p.getId());
@@ -188,7 +187,14 @@ public class IndicatorResource implements IndicatorService {
             });
             dtos.get(key).getIndicators().add(toDTO(indicator, locale));
         }
-        return new ArrayList<>(dtos.values());
+        // sort indicators by name
+        for (final PeriodDTO p : dtos.values()) {
+            Collections.sort(p.getIndicators(), //
+                    (o1, o2) -> o1.getDescription().compareTo(o2.getDescription()));
+        }
+        final List<PeriodDTO> periods = new ArrayList<>(dtos.values());
+        Collections.sort(periods, (o1, o2) -> o1.getDescription().compareTo(o2.getDescription()));
+        return periods;
     }
 
     @GET
@@ -197,7 +203,9 @@ public class IndicatorResource implements IndicatorService {
     @Override
     public Map<String, String> getRegions() {
         return regionDao.findAll().stream()//
-                .collect(Collectors.toMap(r -> String.valueOf(r.getId()), Region::getName));
+                .collect(LinkedHashMap::new, //
+                        (map, item) -> map.put(String.valueOf(item.getId()), item.getName()), //
+                        Map::putAll);
     }
 
     @GET