Ekioo.com tourne sur Blazor et .NET 10 en production. Le site sert du contenu bilingue, un blog, des pages projets et des sitemaps. Cet article explique l'architecture de rendu choisie pour ces besoins et les frontières qui comptent en pratique.
Le pipeline de rendu .NET 10 utilisé par Ekioo
Dans le modèle d'application .NET 10 utilisé par Ekioo, le rendu statique (Static SSR) constitue la base. L'interactivité peut être appliquée localement, héritée d'un parent ou configurée globalement.
Concrètement :
- Les pages par défaut sont rendues en Static SSR : le serveur envoie leur contenu en HTML sans exiger de JavaScript pour l'interactivité.
- Les composants qui ont besoin d'interactivité utilisent un mode de rendu effectif choisi localement, hérité d'un parent ou configuré globalement.
- Les composants en
InteractiveServersont gérés via une connexion temps réel avec le navigateur ; les composants statiques ne conservent pas leur état après la réponse.
Pour la publication principalement statique d'Ekioo et ses interactions isolées, je préfère cette répartition des responsabilités.

Blazor SSR interactif : la frontière à gérer
Les composants en Static SSR produisent une réponse sans conserver leur état. Ceux dont le mode effectif est InteractiveServer utilisent une connexion temps réel avec le navigateur et un circuit côté serveur. Une directive locale peut sélectionner ce mode, mais un composant peut aussi l'hériter d'un parent interactif ou le recevoir d'une configuration globale.
Les pièges du mélange statique / interactif
Ce modèle hybride est puissant mais demande de la discipline.
Problème 1 : les paramètres complexes ne passent pas la frontière
Un parent statique peut passer des paramètres sérialisables en JSON à un composant interactif. Les paramètres impossibles à sérialiser, comme les fragments de rendu ou les autres valeurs de type délégué, ne sont pas pris en charge à cette frontière.
La solution : passer des IDs ou des clés, et laisser le composant interactif aller chercher les données lui-même.
Problème 2 : le prérendu par défaut
Les composants interactifs sont prérendus par défaut. Leur logique d'initialisation peut donc s'exécuter une fois pendant le prérendu, puis de nouveau quand le composant devient interactif.
Pour une opération qui ne doit commencer qu'après l'activation de l'interactivité, utilise OnAfterRenderAsync(bool firstRender), qui n'est pas appelé pendant le prérendu. Pour les données chargées dans les deux phases, persiste l'état prérendu ou désactive le prérendu lorsque c'est pertinent.
Streaming rendering : comportement réel et cas d'usage
Ce que le streaming SSR fait vraiment
Le streaming rendering (activé avec @attribute [StreamRendering]) permet à Blazor d'envoyer le HTML au fur et à mesure que les composants se rendent, sans attendre que toute la page soit prête.
Concrètement : si un composant charge des données lentes (requête base de données, appel API), Blazor peut envoyer le reste de la page immédiatement et "streamer" ce composant quand ses données sont disponibles.
Du point de vue du navigateur : la page commence à s'afficher très rapidement, avec des placeholders pour les parties en attente, puis le contenu final remplace les placeholders sans rechargement visible.
Cas d'usage sur ekioo.com
Sur ekioo.com, le blog liste les articles depuis des fichiers markdown sur disque, donc je n'utilise pas le streaming pour cette liste. Je l'envisagerais pour une section alimentée par des données plus lentes, car Blazor peut afficher des placeholders puis intégrer le contenu final plus tard.
Pièges à connaître
Puisque le contenu final modifie le DOM après les premiers fragments de réponse, je conçois les scripts d'Ekioo pour qu'ils tolèrent ces mises à jour tardives. Dans mes interfaces, je réserve aussi des dimensions stables aux placeholders.
Static SSR et SEO : ce que ça change vraiment
Static SSR : HTML complet, zéro JavaScript requis
En Static SSR pur, le serveur génère le contenu de la page en HTML. Aucun JavaScript n'est nécessaire pour lire ce contenu.
Pour ekioo.com, le bénéfice pratique est direct : le contenu des articles figure dans la réponse HTML initiale. Pour les interfaces diffusées en streaming, je choisis des placeholders aux dimensions stables.
Les métadonnées de mise à jour du sitemap
Ekioo.com expose deux sitemaps : /sitemap.xml (FR + EN) et /sitemap-content.xml (markdown brut). Les dates lastmod sont tirées directement du frontmatter YAML des fichiers markdown.
Google documente lastmod comme la date de la dernière modification significative d'une page et indique pouvoir utiliser cette valeur lorsqu'elle est systématiquement exacte. Ekioo génère ces dates depuis les métadonnées stockées avec chaque fichier Markdown.
Un exemple concret : la navigation bilingue sur ekioo.com
Un cas qui illustre bien les contraintes du modèle SSR :
Ekioo.com est bilingue (FR/EN). La langue vient uniquement de l'URL : pas de cookie, pas de détection Accept-Language et pas de redirection automatique selon la langue. Google recommande des URLs distinctes pour chaque langue et prévient que les redirections automatiques peuvent empêcher les robots de découvrir toutes les versions.
Chaque page de contenu localisée déclare deux routes :
@page "/blog/{Slug}"
@page "/en/blog/{Slug}"
Les pages et composants qui en ont besoin injectent le service LanguageState :
@inject LanguageState Lang
Dans l'implémentation Static SSR d'Ekioo, chaque URL produit une requête indépendante et l'application déduit la langue du chemin de cette requête.
Verdict pour Ekioo
Les contraintes d'Ekioo sont un contenu principalement statique, une publication bilingue, des métadonnées SEO et une codebase C#. Pour ce projet, le Static SSR par défaut et l'interactivité par exception maintiennent le modèle de rendu aligné avec le modèle de contenu.
Il s'agit d'un choix d'architecture propre au projet, pas d'une recommandation universelle. Les applications avec d'autres contraintes d'interaction, d'état ou d'équipe doivent évaluer les modes de rendu disponibles selon leurs propres besoins.
