<?xml version="1.0" encoding="utf-8"?><rss version="2.0">
  <channel>
    <title>Blog Liip</title>
    <link>https://www.liip.ch/fr/blog</link>
    <lastBuildDate>Wed, 06 May 2026 10:49:44 +0200</lastBuildDate>
            <item>
      <title>so.ch: des services cantonaux simplifi&#233;s  pour tou&#183;te&#183;s</title>
      <link>https://www.liip.ch/fr/blog/so-ch-des-services-cantonaux-simplifies-pour-tou-te-s</link>
      <guid>https://www.liip.ch/fr/blog/so-ch-des-services-cantonaux-simplifies-pour-tou-te-s</guid>
      <pubDate>Thu, 07 May 2026 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>Le site so.ch poursuit un objectif clair: permettre à l’usager·ère de traiter tes demandes rapidement, directement et sans détours inutiles. Au lieu de refléter la logique administrative classique «Quel service est responsable?», le site se concentre sur <a href="https://www.liip.ch/fr/services/strategy/understand-users">le besoin r&eacute;el de l&rsquo;utilisateur&middot;trice</a>: «que voulez-vous faire?»</p>
<p>La séparation claire entre Services et Administration rend immédiatement la finalité de la plateforme compréhensible et met en évidence sa valeur pour les habitant·e·s et les entreprises. L’intention du site est ainsi immédiatement perceptible, avec des contenus structurés de manière logique et cohérente. Ce n’est pas seulement notre avis: le jury des BOSW l’a également reconnu en attribuant cette année un bronze dans la catégorie User Experience (un peu de fausse modestie: nous avons occupé deux des trois places du podium, avec également l’argent pour le nouveau site du <a href="https://www.liip.ch/de/work/projects/museum-fur-gestaltung-zurich">Museum f&uuml;r Gestaltung Z&uuml;rich</a>).</p>
<figure class="video"><video controls><source src="https://www.liip.ch/media/pages/blog/so-ch-cantonal-services-made-simple-for-everyone/a93f1aef25-1778057223/liip_bosw_kantonsolothurn.mp4" type="video/mp4"></video></figure>
<h2>Une architecture de l’information pensée utilisateur·rice·s</h2>
<p>L’architecture de l’information est soigneusement conçue et adaptée aux besoins des publics cibles. Tous les services sont centralisés, clairement catégorisés et suivent une structure cohérente pour répondre aux questions: de quoi ai-je besoin, comment se déroule le processus et quels sont les canaux disponibles?</p>
<p>Cette standardisation permet de comprendre rapidement les infos pertinentes et de naviguer avec assurance dans des processus complexes. Les informations sur les services sont aussi présentées de manière transparente, afin que même les utilisateur·rice·s occasionnel·le·s puissent immédiatement identifier les étapes à suivre.</p>
<h2>Fonctionnalité, interactivité et utilisabilité au service de l’efficacité</h2>
<p>Les fonctionnalités du site sont conçues en fonction des besoins des utilisateur·rice·s. Chaque page de service propose des instructions claires et faciles à comprendre, ainsi que des éléments intuitifs et simples à utiliser. Le tout avec un accompagnement à chaque étape: que ce soit via des services numériques ou des canaux plus traditionnels comme des formulaires, des appels téléphoniques ou des visites sur place.</p>
<p>Cette approche réduit les incertitudes, limite les demandes de clarification et améliore l’efficacité dans l’accès aux services cantonaux.</p>
<h2>Un site inclusif conçu pour tou·te·s</h2>
<p>so.ch respecte les normes <a href="https://www.liip.ch/en/services/development/custom-development/accessibility">d&rsquo;accessibilit&eacute; num&eacute;rique</a> conformément aux directives WAI, garantissant un accès équitable à tou·te·s les utilisateur·rice·s. Les contenus sont rédigés de manière claire, la navigation est cohérente, les interactions sont intuitives, et la plateforme prend en charge des accès numériques et non numériques.</p>
<p>Ainsi, chacun·e peut utiliser le site de manière efficace et autonome, indépendamment de son expérience technique, de son âge ou de ses capacités.</p>
<p>En se concentrant systématiquement sur les besoins des utilisateur·rice·s, so.ch propose une plateforme intuitive, transparente et inclusive qui rend les processus administratifs complexes compréhensibles. Des objectifs clairs, une architecture de l’information réfléchie, des fonctionnalités accessibles et un design sans barrières créent une expérience centrée sur l’utilisateur·rice. Ce qui permet de simplifier et optimiser les interactions avec les services cantonaux.</p>
<p>Souhaitez-vous améliorer le site web de votre organisation? Je serais <a href="https://www.liip.ch/fr/team/philipp-klein">ravi d&rsquo;en savoir plus sur vos besoins et vos d&eacute;fis</a>.</p>]]></description>
    </item>
        <item>
      <title>Qui a encore besoin d&#039;un apprentissage quand l&#039;IA est l&#224;?</title>
      <link>https://www.liip.ch/fr/blog/qui-a-encore-besoin-d-un-apprentissage-quand-l-ia-est-la</link>
      <guid>https://www.liip.ch/fr/blog/qui-a-encore-besoin-d-un-apprentissage-quand-l-ia-est-la</guid>
      <pubDate>Tue, 21 Apr 2026 00:00:00 +0200</pubDate>
      <description><![CDATA[<h3>L'IA fait déjà partie de mon quotidien</h3>
<p>Au fin 2022, j'ai vu ChatGPT pour la première fois dans une vidéo TikTok et je l'ai tout de suite essayé. Il pouvait m'expliquer des contenus plus rapidement que mes enseignant·e·s, résoudre des tâches mieux que si je les avais faites moi-même, et même développer des idées auxquelles je n'aurais jamais pensé. Ça m'a vraiment fasciné.</p>
<p>Mais c'est seulement en commençant mon apprentissage que j'ai réalisé à quel point l'IA est puissante et importante. Aujourd'hui, je l'utilise quotidiennement. Pas pour qu'elle fasse mon travail à ma place, mais pour apprendre de nouvelles choses, faire des recherches plus efficacement et travailler plus efficacement sur certaines tâches.</p>
<h3>Mon apprentissage est varié. C'est justement ce qui le rend passionnant</h3>
<p>J'effectue un <a href="https://www.ict-berufsbildung.ch/formation-initiale/apprentissages-ict/developpeurse-de-business-numerique-cfc">apprentissage de Développeur·euse en Commerce Numérique CFC</a>. J'en suis actuellement à ma deuxième année. Après la première année au Bbc Basislehrjahr, j'ai rejoint Liip durant l'été 2025.</p>
<p>Ce que je trouve particulièrement passionnant dans cet apprentissage, c'est la diversité des tâches. Je travaille dans différents Circles, des équipes auto-organisées basées sur l'holacratie. Cela me permet de découvrir de nombreuses perspectives, tâches et personnes différentes.</p>
<figure><img alt="" src="https://liip.rokka.io/www_inarticle_5/ccafe5/grafik-1.jpg" srcset="https://liip.rokka.io/www_inarticle_5/o-dpr-2/ccafe5/grafik-1.jpg 2x"></figure>
<p>Cette variété me correspond bien. J'aime travailler de façon structurée, je communique activement et je trouve stimulant d'analyser et d'améliorer les processus de travail. Chez Liip, j'ai la chance de pouvoir prendre des responsabilités tôt dans mon apprentissage. Je travaille sur des projets internes et externes concrets, je prends des décisions et j'apporte mes propres idées. Pour moi, c'est ce qui distingue vraiment Liip de nombreux autres employeurs proposant des apprentissages.</p>
<h3>La relation avec les clients en fait partie</h3>
<p>Un aspect de mon apprentissage peut-être moins visible de l'extérieur réside dans la relation avec les clients. J'apprends à communiquer de façon professionnelle, à bien représenter mon entreprise et à comprendre les facteurs importants pour une bonne collaboration. Cela implique notamment de transmettre des informations claires au sein de l'équipe, de recueillir des exigences et de communiquer de manière structurée dans les projets. Parce que je participe à de vrais projets dès le début de mon apprentissage, je développe rapidement un bon sens de ce qui compte réellement pour les clients.</p>
<h3>Comment j'utilise l'IA concrètement</h3>
<p>L'IA devient particulièrement utile quand je lui fournis beaucoup de contexte. Un outil généraliste se transforme alors en véritable partenaire de réflexion. L'IA me soutient surtout quand j'ai un objectif clair et que j'ai besoin d'une bonne première ébauche rapidement. Je l'utilise pour brainstormer, comprendre de nouveaux termes, faire des recherches ou structurer des textes.</p>
<ul>
<li><em>Anecdote au passage: ce billet de blog a aussi été partiellement structuré avec l'IA. J'ai rassemblé mes idées, expliqué le contexte, puis j'ai reçu de l'aide pour créer une structure cohérente. C'est comme ça que j'utilise l'IA au quotidien.</em></li>
</ul>
<p>Un bon exemple est le manuel pour le backend <a href="https://www.liip.ch/fr/work/projects/liipgpt">LiipGPT</a> que j'ai rédigé. Au départ, je n'avais pratiquement aucune expérience dans la rédaction de manuels. J'ai donc d'abord appris les bases avec l'aide de l'IA. Ensuite, j'ai fourni un maximum de contexte à l'IA et développé une ébauche étape par étape avec elle. Le résultat est un manuel utilisé régulièrement en interne et adapté individuellement pour les clients. Pour moi, c'est le moment où j'ai réalisé la valeur ajoutée que l'IA peut apporter: je pouvais non seulement travailler plus vite et sans expérience préalable, mais aussi créer un résultat qui aide vraiment les autres dans leur quotidien.</p>
<figure><img alt="" src="https://liip.rokka.io/www_inarticle_5/2b6bdf/grafik-2-fr.jpg" srcset="https://liip.rokka.io/www_inarticle_5/o-dpr-2/2b6bdf/grafik-2-fr.jpg 2x"></figure>
<aside>
<blockquote>
<h3>Mes 3 outils IA incontournables au quotidien en Digital Business</h3>
</blockquote>
<p>Un aperçu rapide des outils qui m'aident le plus au quotidien:</p>
<ul>
<li>
<p><strong>Claude</strong></p>
<p>Mon outil principal pour le brainstorming, la rédaction et la compréhension de nouveaux sujets.</p>
</li>
<li>
<p><strong>Cursor</strong></p>
<p>M'aide dans le code, même sans compétences avancées en programmation. Pour un outil de rendu dans Figma, j'ai d'abord expliqué le contexte en mode Plan, puis je l'ai implémenté étape par étape. Cursor m'a vraiment aidé à concrétiser l'idée.</p>
</li>
<li>
<p><strong>NotebookLM</strong></p>
<p>J'y télécharge des documents ou des notes et j'en tire des résumés, des questions ou du matériel d'apprentissage condensé. Particulièrement utile pour les examens ou pour se familiariser avec de nouveaux sujets.</p>
<blockquote>
</aside>
</blockquote>
</li>
</ul>
<p>Je n'utilise pas ces outils sans réfléchir. Je les teste, je les compare et je réfléchis soigneusement aux cas d'usage où ils ont pleinement du sens.</p>
<h3>L'IA, mon meilleur compagnon d'apprentissage</h3>
<p>L'IA a un fort potentiel pour l'apprentissage. Elle simplifie les contenus, donne des exemples et s'adapte à mon niveau. Aucun manuel ne peut faire ça. Prendre en main un nouveau sujet devient ainsi plus rapide. En tant qu'apprenti·e, je pose à l'IA des questions et des questions de suivi que je n'oserais pas poser en classe.</p>
<p>En même temps: <strong>l'IA ne doit jamais remplacer ta propre réflexion. Ceux et celles qui ne comprennent pas comment l'IA fonctionne et comment l'utiliser finiront par très peu apprendre.</strong></p>
<p>Pour moi, l'ouverture d'esprit et le questionnement critique font partie intégrante de l'utilisation de nouveaux outils. L'IA peut autonomiser les apprenant·e·s, mais uniquement si elle est utilisée consciemment comme un outil. C'est pourquoi il est important que les apprenti·e·s se familiarisent avec l'IA pendant leur formation. Pas plus tard, quand tout le monde sera déjà utilisateur·rice chevronné·e.</p>
<h3>Et toi, comment utilises-tu l'IA?</h3>
<p>Peut-être vaut-il la peine de faire une courte pause après ce billet de blog et de réfléchir à ta propre utilisation de l'IA. Comment utilises-tu vraiment l'IA dans ton quotidien aujourd'hui? Quelle valeur ajoutée concrète t'apporte-t-elle? Est-ce simplement un outil que tu essaies de temps en temps? Ou est-ce que tu l'utilises consciemment pour travailler mieux, plus vite ou de façon plus structurée?</p>
<p>Chez Liip, je vis directement comment une organisation n'utilise pas seulement l'IA, mais la façonne activement:</p>
<ul>
<li>des échanges de connaissances réguliers et des Liip Talks sur l'IA, des nouveaux modèles aux questions éthiques.</li>
<li>des formations à l'IA pour tou·te·s les collaborateur·rice·s. En interne, nous proposons des ateliers et des modules spéciaux pour que chacun·e reste à l'aise avec l'utilisation de l'IA.</li>
<li>le développement et la mise à jour de nos propres outils IA comme <a href="https://www.liip.ch/en/work/projects/liipgpt">LiipGPT</a>, déjà utilisé par des clients des secteurs de la santé, du droit et du secteur public.</li>
<li>des <a href="https://www.liip.ch/fr/blog/faconner-l-ia-pour-les-personnes-et-la-planete">lignes directrices sur l'IA durable</a>, un cadre interne qui garantit que les projets d'IA sont mis en oeuvre de façon éthique et durable.</li>
</ul>
<p>Cela me montre à quoi peut ressembler une organisation qui ne déploie pas l'IA aveuglément, mais qui en assume la responsabilité.</p>
<p>Comment les collaborateur·rice·s de ton entreprise utilisent-ils·elles l'IA? Y a-t-il des règles claires ou des offres pour utiliser l'IA de façon pertinente? Où l'IA pourrait-elle concrètement te soutenir dans ton rôle si tu l'utilisais de manière plus délibérée?</p>
<p>L'IA n'est pas un concept figé qui fonctionne de la même manière pour tout le monde. Mais ceux et celles qui l'utilisent tôt réalisent rapidement: <strong>la question n'est pas de savoir si tu as encore besoin d'un apprentissage, mais combien tu en tires davantage grâce à l'IA.</strong></p>]]></description>
    </item>
        <item>
      <title>Retour sur BOSW 26</title>
      <link>https://www.liip.ch/fr/blog/retour-sur-bosw-26</link>
      <guid>https://www.liip.ch/fr/blog/retour-sur-bosw-26</guid>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>Comme chaque année, The Hall à Dübendorf a réuni un véritable who’s who de l’industrie web suisse pour récompenser les meilleurs projets de l’année dans différentes catégories. De notre côté, nous avons soumis trois projets cette année, tous sélectionnés dans la shortlist. Il s’agit des plateformes digitales développées pour le Museum für Gestaltung Zürich, le portail carrière Migros et le nouveau site du canton de Soleure. La cérémonie de remise des prix a été l’occasion pour les membres des équipes projet, côté client comme chez Liip, de se retrouver. Mais surtout, c’était un moment rempli de suspense pour découvrir quels projets remporteraient l’or, l’argent ou le bronze.</p>
<h2>Museum für Gestaltung: un chef-d’œuvre d’intérêt public et d’expérience utilisateur</h2>
<p>Le nouveau site du Museum für Gestaltung Zürich sert de hub central pour la communication digitale du musée et permet aux visiteur·euse·s de créer un lien avec celui-ci. En co-création, nous avons conçu une solution qui laisse le design s’exprimer pleinement, au service d’une plus grande valeur publique. Le jury des BOSW l’a reconnu en attribuant au site le prix d’argent dans les catégories “User Experience” et “Public Value”.</p>
<p>En savoir plus sur le <a href="https://www.liip.ch/en/work/projects/museum-fur-gestaltung-zurich">projet prim&eacute;</a> </p>
<p>Comme le souligne Clelia Kanai, Head of Marketing &amp; Communication:<br />
«Pour nous, le design signifie clarté et responsabilité – y compris dans le domaine numérique. Avec Liip, nous avons trouvé un partenaire qui partage et porte ces valeurs, de la conception initiale jusqu’à la vérification finale de l’accessibilité. Le fait que ce projet ait été récompensé par deux prix d’argent aux BOSW, dans les catégories User Experience et Public Value, est à la fois une validation et une magnifique reconnaissance pour nous.»</p>
<figure><img alt="" src="https://liip.rokka.io/www_inarticle_5/e48782/bosw2026teampic.jpg" srcset="https://liip.rokka.io/www_inarticle_5/o-dpr-2/e48782/bosw2026teampic.jpg 2x"></figure>
<h2>so.ch: transparence, accessibilité et simplicité pour renforcer la confiance du public</h2>
<p>Nous avons développé un nouveau site pour le canton de Soleure, so.ch. Il crée une véritable valeur publique en rendant les services cantonaux transparents, accessibles et faciles à comprendre, renforçant ainsi la confiance du public, des autorités locales et des acteur·rice·s économiques dans les services publics.</p>
<p>Comme bs.ch nous l’a montré l’an dernier, un site centré utilisateur·rice est essentiel pour améliorer le quotidien des citoyen·ne·s, qui doivent de plus en plus accéder à leurs informations et documents en ligne. Le jury a reconnu la qualité de l’expérience utilisateur de so.ch  en attribuant le bronze dans cette catégorie clé.</p>
<p>En savoir plus sur le <a href="https://www.liip.ch/en/work/projects/so-ch-user-experience">projet prim&eacute;</a></p>
<p>Même si nous n’avons pas remporté autant de prix que nous l’aurions souhaité (et que nous pensons bien sûr mériter :), c’était une belle occasion de prendre le pouls du secteur. Nous félicitons chaleureusement « Swissgrid 24/7 », Master of Swiss Web 26. À l’année prochaine!</p>]]></description>
    </item>
        <item>
      <title>Zurich Climate Week</title>
      <link>https://www.liip.ch/fr/blog/zurich-climate-week</link>
      <guid>https://www.liip.ch/fr/blog/zurich-climate-week</guid>
      <pubDate>Thu, 16 Apr 2026 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>La première <a href="https://www.climateweekzurich.org/" rel="noreferrer" target="_blank">Zurich Climate Week</a> (du 4 au 9 mai) est lancée et elle arrive à vrai dire au bon moment. Dans le contexte géopolitique actuel, l’initiative aurait pu échouer. C’est tout le contraire: l’accueil est extrêmement positif, l’écho et la participation sont importants et certaines autres villes nous envient déjà… et viennent simplement à Zurich pour en faire partie.</p>
<p>À la lumière des récents développements politiques, un « do-talk gap » a (une fois de plus) été constaté dans le domaine de la durabilité. La Zurich Climate Week s’attaque précisément à ce point: s’engager face à l’urgence climatique et en parler.</p>
<p>Et c’est exactement ce dont nous avons besoin aujourd’hui. Car la transformation durable ne se fait pas en silence. Elle naît là où des perspectives différentes se rencontrent: économie, politique, recherche et société civile. Là où les connaissances sont partagées. Là où des solutions sont développées et mises à l’échelle ensemble.</p>
<h1>Pourquoi nous nous engageons</h1>
<p>Chez Liip, nous avons décidé de contribuer au programme de la Zurich Climate Week pour plusieurs raisons:</p>
<ul>
<li>Pour soutenir l’initiative en participant activement au programme</li>
<li>Pour renforcer notre engagement en faveur de la durabilité au-delà de la Climate Week</li>
<li>Et surtout: pour partager nos expériences, apprendre des autres et élargir notre réseau de personnes engagées</li>
</ul>
<p>Notre contribution à la Climate Week, tout comme les deux thématiques de nos événements, s’inscrit selon un même principe: <strong>assumer notre responsabilité</strong>.</p>
<h1>Notre contribution</h1>
<p>Liip est présent dans le programme avec deux formats, tous deux axés sur l’échange, la pratique et la mise en œuvre concrète.</p>
<h2>Hacking for Sustainable AI</h2>
<p><a href="https://climateweekzurich.glueup.com/event/hacking-for-sustainable-ai-176395/" rel="noreferrer" target="_blank">Plus d&rsquo;informations &amp; inscription</a></p>
<p>L’intelligence artificielle fait désormais partie de notre quotidien. Elle semble offrir des solutions à de nombreux problèmes et constitue souvent le premier réflexe lorsque nous arrivons à une impasse. Pourtant, ses impacts environnementaux et sociétaux restent encore largement sous-estimés.</p>
<p>Dans quels cas l’IA crée-t-elle réellement de la valeur? Et comment l’utiliser de manière à contribuer à un avenir plus durable?</p>
<p>En collaboration avec <a href="http://opendata.ch" rel="noreferrer" target="_blank">opendata.ch</a>, nous mettons ces questions au centre d’un mini hackathon. Développeur·euse·s, designer·euse·s, expert·e·s en durabilité, entreprises et toute personne intéressée sont invité·e·s à imaginer ensemble de nouvelles idées, prototypes et perspectives.</p>
<p>👉 Objectif: développer des approches concrètes pour utiliser l’IA de manière pertinente, responsable et à fort impact.</p>
<h2>Sustainability Reporting for SMEs: Real Cases, Practical Steps</h2>
<p><a href="https://climateweekzurich.glueup.com/event/sustainability-reporting-for-smes-real-cases-practical-steps-176404/" rel="noreferrer" target="_blank">Plus d&rsquo;informations &amp; inscription</a></p>
<p>Les PME jouent un rôle central dans la transformation durable. Et pourtant, beaucoup se posent les mêmes questions: par où commencer? Qu’est-ce qui est vraiment pertinent? Et quel est le niveau d’effort nécessaire?</p>
<p>Dans cette session, 4 PME partagent leur expérience du reporting de durabilité volontaire.</p>
<p>Le format est interactif: sous forme de table ronde, les participant·e·s peuvent poser des questions, partager leurs propres approches et discuter ensemble des moyens de surmonter les obstacles.</p>
<p>👉 Objectif: réduire les difficultés de départ, montrer que le premier pas est accessible et faire grandir une communauté de PME engagées.</p>
<h1>Du discours à l’action collective</h1>
<p>La Zurich Climate Week incarne un état d’esprit que nous partageons: allier urgence et optimisme. Ne pas seulement parler des problèmes, mais faire avancer des solutions concrètes. Assumer ensemble notre responsabilité et générer un impact réel.</p>
<p>Dans un contexte où les incertitudes augmentent et où les priorités évoluent, il est plus important que jamais de rester engagés. La durabilité n’est pas une tendance à court terme mais bien une nécessité à long terme. Et en même temps, une opportunité: pour l’innovation, pour de nouveaux modèles économiques, pour une différenciation réelle et au final pour une meilleure qualité de vie.</p>
<p>Ce dont nous avons besoin, ce sont davantage d’espaces d’échange. Plus de transparence. Et plus de courage pour partager ce qui est encore en construction.</p>
<p>La Zurich Climate Week crée précisément ces espaces. Nous sommes ravis d’en faire partie.</p>]]></description>
    </item>
        <item>
      <title>Iframes are still odd</title>
      <link>https://www.liip.ch/fr/blog/iframes-are-still-odd</link>
      <guid>https://www.liip.ch/fr/blog/iframes-are-still-odd</guid>
      <pubDate>Mon, 23 Mar 2026 00:00:00 +0100</pubDate>
      <description><![CDATA[<h2>The Challenge</h2>
<p>The application does one - rather complicated - task, with lots of business logic. There was no way we could rewrite it to include it directly into the website code. And because the application comes with its own Javascript and CSS, we decided to use an iframe to embed the application with clean isolation.</p>
<p>The company maintaining that application provided us with a version - running as a Docker container - where they had stripped all extra elements like the navigation, so that it would visually fit within the website. There was however no way for us to customise anything within the application.</p>
<h2>iframe security</h2>
<p>The promise of an iframe is to keep a clean security boundary between embedding page and embedded content. This means that it is by design not possible to call Javascript across the boundary. </p>
<p>Because injecting iframes could potentially trick a user into submitting data to an attacker (clickjacking), as the iframe may be from a different origin than the main page. Thus, to even render the iframe, the browser checks the Content-Security-Policy (CSP) HTTP header. That header has a field frame-src to control what may be included as an iframe. With this, I allowed the domain of the application to be included in iframes.</p>
<pre><code>Content-Security-Policy: frame-src https://my-embed.com;</code></pre>
<p>But not only does the including page need to allow an iframe. The page to be embedded also needs to allow being included with the frame-ancestors attribute of the CSP header. As we run the application Docker image under our control, I was able to add that header in the proxy that runs before the Docker image:</p>
<pre><code>Content-Security-Policy: frame-ancestors https://my-website.com;</code></pre>
<p>Several things to note:</p>
<ul>
<li>If you have other CSP rules, merge them with the rules, nginx will overwrite the header and not add to it</li>
<li>Both options also support "self" to allow embedding resp. being embedded with the same webserver</li>
<li>Prior to the CSP becoming a standard, there was an unofficial header <code>X-Frame-Options</code>, which is still supported by browsers</li>
<li><code>Content-Security-Policy</code> must be an actual HTTP header, <code>&lt;meta http-equiv=”...”&gt;</code> is ignored for <code>Content-Security-Policy</code> (and also ignored for <code>X-Frame-Options</code>).</li>
</ul>
<h2>Size of the iframe element</h2>
<p>Now we get to the weird parts. To prevent multiple scrollbars, we need the iframe element to be exactly big enough for the embedded page. If it is too small, there is an additional scrollbar (or hidden content). If it is too large, there is odd whitespace.</p>
<p>The size of the element needs to be set on the iframe, owned by the parent. The dimensions of the content are however only known by the embedded application. HTML / CSS do not provide any means to let the parent page declare that it wants the iframe to have the “necessary size”. </p>
<p>We ended up with a really convoluted way, which seems the only way to achieve this: sending messages from the child page to the parent. This problem spawned dedicated javascript libraries like <a href="https://github.com/davidjbradshaw/iframe-resizer">iframe-resizer</a>. We ended up reimplementing the logic in the React application, as it was so small that a dedicated library felt like overkill. Following the tutorial at <a href="https://github.com/craigfrancis/iframe-height/">iframe-height</a> (which also has some interesting background on the discussion about iframes in the Whatwg), we came up with this code for the containing website:</p>
<pre><code class="language-js">// register an event listener for messages
window.addEventListener('message', receiveMessage, false);

// handle a message
function receiveMessage(event) {
    const origin = event.origin || event.originalEvent.origin;
    // we configure the expected domain to allow for this additional sanity check
    if (expectedDomain !== origin) {
      return;
    }
    if (!event.data.request || 'iframeResize' !== event.data.request) {
      return;
    }
    // the id is known in the js class. we need to find the element that needs to be resized
    const iframe = document.getElementById(`iframe-${id}`);
    if (iframe) {
      // pad the height a bit to avoid unnecessary tiny scrolling
      iframe.style.height = (event.data.height + 20) + 'px';
      // width could be handled the same way if necessary - in our case the width is fix
    }
}</code></pre>
<p>Now we need to make the embedded content send a message with its height. The Javascript for that is a bit verbose to allow for different browsers, but not complicated either:</p>
<pre><code class="language-js">(
    function(document, window) {
      if (undefined === parent || !document.addEventListener) {
        return;
      }
      function init() {
        let owner = null;
        const width = Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);
        const height = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
        if (parent.postMessage) {
          owner = parent;
        } else if (parent.contentWindow &amp;&amp; parent.contentWindow.postMessage) {
          owner = parent.contentWindow;
        } else {
          return;
        }
        owner.postMessage({
          'request' : 'iframeResize',
          'width' : width,
          'height' : height
        }, '*');
      }

      if (document.readyState !== 'loading') {
        window.setTimeout(init);
      } else {
        document.addEventListener('DOMContentLoaded', init);
      }
      // this is needed to also adjust the iframe if something (e.g. the Javascript of the application) changes the size of the iframe without an actual page reload.
      const observer = new ResizeObserver(init);
      observer.observe(document.body);
    }
  )(document, window);"</code></pre>
<h3>iframes with same origin</h3>
<p>If the iframe comes from the same origin (= domain) as the parent page, Javascript can cross the boundary. From parent to child, there is a <code>contentWindow</code> property on the <code>iframe</code> element. From child to parent, there is <code>window.parent</code>. With same origin, those elements expose all things the window usually has. For different origins, they only expose the function <code>postMessage</code> for the secure separation.</p>
<h2>Injecting content with Nginx</h2>
<p>Remember how I said we can’t modify the application? That still holds true. If we would have loaded both applications from the same domain, we could have had the parent page add a listener inside the iframe to directly update dimensions as needed. But the application contained absolute paths for its assets, so providing it from a subfolder of the same domain would have been tricky and we had to run it on a separate domain. </p>
<p>I ended up injecting the above snippet of Javascript in the Nginx proxy that sits in front of the Docker container:</p>
<pre><code>proxy_set_header Accept-Encoding ""; # make sure we get plain response for substitution to work
...
sub_filter_last_modified on;
sub_filter "&lt;/body&gt;" "&lt;script language='javascript'&gt;${script}&lt;/script&gt;&lt;/body&gt;";
sub_filter_once on;
...
proxy_pass https://my-embed.com$request_uri;</code></pre>
<p>Now the embedded iframe communicates its size to the containing page, which adjusts the iframe size accordingly.</p>
<p>(Note that Nginx does not execute these statements in order. The sub_filter instructions apply to the response, wihle proxy_set_header and proxy_pass apply to the request.)</p>
<h2>Alternatives</h2>
<p>Web Components are a more lightweight solution to combine separate sources into one website. If what you need to integrate is just an element and not a whole application, they might be a better fit. My collegue Falk wrote about <a href="https://www.liip.ch/en/blog/web-components-the-good-the-bad-and-the-ugly">Web Components</a> last week.</p>
<hr />
<h2>Bonus: Access control for the iframe content</h2>
<p>Because the application is not under our control, we need to manage access to it. We told the supplier of the application to remove access control and simply allow items to be created and edited by ID. Of course, this means that the application must never be directly exposed to the internet, but only reachable through the proxy.</p>
<p>On the embedding side, we track which user is allowed what ids, and have Nginx do a pre-flight check against the website to get the access decision:</p>
<pre><code># at the beginning of the location for the main request to the embeded application
auth_request /auth;

location /auth {
    # preflight authorization request with symfony
    fastcgi_pass phpfcgi;
    include /usr/local/openresty/nginx/conf/fastcgi_params;
    fastcgi_param SCRIPT_FILENAME /app/public/index.php;
    # forward the original request URI to allow our main application to verify access to the specific resource
    fastcgi_param REQUEST_URI /embed-check$request_uri;
    # body is not forwarded. we have to remove content length separately, otherwise PHP-FPM will wait for the body until the auth request times out.
    fastcgi_pass_request_body off;
    fastcgi_param CONTENT_LENGTH "";
    fastcgi_param CONTENT_TYPE "";
    internal;
}</code></pre>
<p>If the call at <code>/embed-check/...</code> returns a 2xx status, Nginx continues with the request, otherwise it returns the response with the status code to the client, allowing for example to redirect to the login page. In my case, i return an empty response with status 204 if the user is allowed to access the specific resource.</p>
<p>On Symfony side, I use Symfony security to make sure the user is logged in. And then parse the path to know which item in the application the request wants to access, and check if the user has access. This leaks knowledge about the URL design of the embedded application, which is not avoidable for granular access control.</p>]]></description>
    </item>
        <item>
      <title>Preventing Context Pollution for AI Agents</title>
      <link>https://www.liip.ch/fr/blog/preventing-context-pollution-for-ai-agents</link>
      <guid>https://www.liip.ch/fr/blog/preventing-context-pollution-for-ai-agents</guid>
      <pubDate>Wed, 18 Mar 2026 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>Context pollution happens when the context window fills up with information that is irrelevant to the current task. The more an agent has to juggle, the more likely it loses track of what it was actually doing.</p>
<p>Here are practical techniques to prevent it.</p>
<h2>Session Hygiene</h2>
<p>Start a fresh session for each task. This is the simplest technique and the easiest to get right. If earlier research is needed, write it into a temporary handoff file and let a new session pick up from there.</p>
<h2>Streamline Tool Calling</h2>
<p>Every tool call adds tokens to the context. Poorly built tools add a lot of them. To keep the context lean:</p>
<ul>
<li>Choose tools and MCPs that are well built and optimize token usage</li>
<li>Make sure via prompting that the right tools are used from the start</li>
</ul>
<p>A single bloated tool response can waste more context than an entire conversation turn.</p>
<h2>Subagents</h2>
<p>Agents can spawn other agents that run in their own context. This isolates work and keeps the parent context clean. It helps most when building large features where individual parts are independent.</p>
<p>The easiest way to use subagents is to prompt something like:</p>
<pre><code>Split the current plan into tasks, use a subagent for each task.</code></pre>
<h2>Persistent Tasks</h2>
<p>I built an MCP for Claude Code called <code>deliverables-mcp</code> that lets an agent create persistent tasks per codebase. Tasks are stored in <code>.claude/deliverables.jsonl</code> and persist across sessions.</p>
<p>This allows:</p>
<ul>
<li>Starting a new session before implementing each task</li>
<li>Running subagents in parallel based on tasks dependencies</li>
<li>Restarting a failed task in a clean session</li>
</ul>
<p>The tool replaces Claude Code's internal tasks and is deliberately called "deliverables" for two reasons:</p>
<ol>
<li>To avoid confusing the agent with two tools both called "tasks"</li>
<li>Deliverables are typically larger than just a task, which is a sweet spot for AI agents. Not so small that handoff cost dominates, but small enough that context problems are rare.</li>
</ol>
<p>You can check out <code>deliverables-mcp</code> on <a href="https://github.com/FalkZ/deliverables-mcp">GitHub</a>.</p>]]></description>
    </item>
        <item>
      <title>Le chatbot ConfIAnce, un an apr&#232;s</title>
      <link>https://www.liip.ch/fr/blog/le-chatbot-confiance-un-an-apres</link>
      <guid>https://www.liip.ch/fr/blog/le-chatbot-confiance-un-an-apres</guid>
      <pubDate>Tue, 17 Mar 2026 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>Il y a un peu moins d’un an, nous vous avions présenté <a href="https://www.liip.ch/fr/blog/confiance-premier-chatbot-llm-de-medecine-generale-en-suisse">le chatbot ConfIAnce</a>. Mandaté par les HUG, nous avons développé ce robot conversationnel dont l’objectif est de proposer un accès facilité et interactif aux informations médicales produites sur les maladies chroniques courantes et validées par l’établissement médical. </p>
<p>Un article publié par les initiateurs et initiatrices de ce projet dans le dernier numéro de la Revue Médicale Suisse dresse un bilan provisoire, un an après la mise en ligne publique.</p>
<figure><img alt="" src="https://liip.rokka.io/www_inarticle_5/9661ee/rms-confiance.jpg" srcset="https://liip.rokka.io/www_inarticle_5/o-dpr-2/9661ee/rms-confiance.jpg 2x"></figure>
<h2>Un chatbot officiel plutôt que des réponses parfois erronées sur le net</h2>
<p>La médecine de premier recours, essentielle au bon fonctionnement du système de santé, fait face à une pénurie croissante, même en ville. Faute d’accès à leur médecin traitant, les patients sont incités à rechercher des réponses sur internet, qui sont souvent erronées voire dangereuses. </p>
<p>Dans ce contexte, une solution IA bien pensée pourrait apporter <strong>la bonne information au bon moment</strong>.</p>
<p>C’est pourquoi nous avons accompagné les HUG à développer un chatbot de type <strong>RAG (Retrieval Augmented Generation)</strong>. ConfIAnce n’est pas le premier chatbot destiné aux patients. Cependant, il se distingue par “son ancrage institutionnel, l’utilisation de contenus médicaux validés localement, et la mise en place de couches de contrôle pour garantir la fiabilité des réponses”. </p>
<p>Pour garantir la sécurité, il intègre des systèmes de contrôle rigoureux: <strong>matching, groundedness, harmfulness, tests automatiques, routage sémantique</strong>.</p>
<h2>Garder le contrôle de l’outil pour assurer la qualité</h2>
<p>L’un des enjeux est de bien garder le contrôle de l’outil, ce qui nécessite des fonctionnalités de surveillance du chatbot. Pour ce faire, des tests automatisés sont effectués sur l’ensemble des réponses apportées aux questions posées. On y mesure la cohérence factuelle de la réponse générée par le chatbot par rapport au contenu de la base de connaissances (faithfullness).</p>
<p>De plus, un routage, ajustable par les administrateurs, garantit un contrôle humain en filtrant et en dirigeant les questions de manière appropriée. Les administrateurs peuvent aussi mettre le chatbot immédiatement hors ligne en cas de suspicion de dysfonctionnement.<br />
Les thèmes peu abordés dans les documents sources et qui sont pourtant un sujet de questions vont aussi être développés pour enrichir la base de connaissances dans <strong>un processus d’amélioration continue</strong>. </p>
<h2>Un tel outil, aussi performant soit-il, n’est utile que s’il est adopté</h2>
<p>Pour que le chatbot soit utilisé par les patients, les HUG ont mené une campagne d’information publique. L’objectif était de promouvoir l’outil, tout en restant réaliste quant aux attentes des patient·e·s. </p>
<p>Ce n’est <strong>pas un dispositif médical qui se substitue à une visite</strong>, mais bien un soutien informationnel permettant de répondre à des questions portant sur les maladies chroniques les plus courantes chez les adultes.</p>
<p>En février 2025, ConfIAnce sort en version beta. Entre début février et fin octobre 2025, 3'823 utilisateurs ont interagi avec le chatbot, donnant lieu à 5'969 conversations et <strong>11'781 questions</strong> (soit environ deux questions par conversation). </p>
<p>Les feedbacks donnés directement au chatbot sont à <strong>75% positifs</strong>. </p>
<h2>Une bonne acceptabilité de ce chatbot différent des autres</h2>
<p>Si les chatbots dans le parcours de santé sont bien acceptés par les patients par leur disponibilité continue et leur facilité d’usage, des études montrent que les problèmes décelés concernent l’hétérogénéité de la qualité des réponses données et l’opacité des sources utilisées. </p>
<p>Ce sont là des éléments qui permettent de distinguer ConfIAnce d’autres chatbots médicaux. </p>
<p>Destiné à <strong>encourager, et non à remplacer, les relations directes entre les patients et les médecins</strong>, ConfIAnce “permet de soutenir les médecins de premier recours en leur libérant du temps de qualité pour pratiquer avec humanité le métier qu’ils ont choisi d’exercer.”</p>
<p>Les auteur·rices de l’article de la Revue Médicale Suisse soulignent à quel point ce chatbot développé dans le contexte spécifique des HUG et de leurs bases d’information peut être transposé dans d’autres contextes institutionnels. Pour que la réussite soit au rendez-vous, il nous semble nécessaire de bénéficier d'abord de <strong>données de qualité</strong> comme c’était le cas ici. Mais ce n’est pas tout, <strong>les couches de contrôle, les tests automatiques et les feedbacks utilisateurs</strong> permettent ensuite une amélioration continue pour garantir la sécurité et la pertinence nécessaires à la confiance.</p>]]></description>
    </item>
        <item>
      <title>Rendre LiipGPT accessible: notre parcours vers la conformit&#233; WCAG-AA</title>
      <link>https://www.liip.ch/fr/blog/rendre-liipgpt-accessible</link>
      <guid>https://www.liip.ch/fr/blog/rendre-liipgpt-accessible</guid>
      <pubDate>Mon, 16 Mar 2026 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>Après nous être d’abord concentré·e·s sur l’approche thématique de notre chatbot <a href="https://www.liipgpt.ch/" rel="noreferrer" target="_blank">LiipGPT</a> — présentée récemment lors du <a href="https://zuericitygpt.ch/" rel="noreferrer" target="_blank">relaunch de Z&uuml;riCityGPT</a> — nous avons orienté notre attention vers l’accessibilité avec pour objectif d’atteindre la conformité WCAG-AA. Comme pour beaucoup de fonctionnalités, nous avons d’abord observé comment les référence du secteur comme ChatGPT, Perplexity et Claude traitent l’accessibilité. Bien que nous ayons constaté un potentiel d’amélioration partout, cela nous a inspiré·e·s à réfléchir à la manière de faire mieux de notre côté.</p>
<p>Notre parcours vers l’accessibilité s’est articulé autour de quatre étapes principales: des scans automatiques et quick fixes, la navigation au clavier, l’optimisation pour le zoom mobile ainsi que l’optimisation pour les lecteur·rice·s d’écran.</p>
<h2>Scans automatiques et quick fixes</h2>
<p>Nous avons commencé par des tests automatisés d’accessibilité à l’aide d’extensions de navigateur comme <a href="https://chromewebstore.google.com/detail/ibm-equal-access-accessib/lkcagbfjnkomcinoddgooolagloogehp" rel="noreferrer" target="_blank">IBM Equal Access Accessibility Checker</a> et <a href="https://www.deque.com/axe/devtools/extension" rel="noreferrer" target="_blank">axe DevTools</a>. Ces outils nous ont aidé·e·s à identifier des problèmes fréquents: labels manquants, contraste de couleurs insuffisant, HTML sémantique incorrect et attributs ARIA absents. Bien que les scans automatisés ne détectent qu’environ 40 % des problèmes d’accessibilité, ils constituent une base  de départ solide.</p>
<h2>Navigation au clavier</h2>
<p>Une navigation correcte au clavier est fondamentale pour l’accessibilité. Garantir que la navigation de base avec la touche Tab fonctionne dans toute l’application est relativement simple. Des composants plus complexes comme les <a href="https://www.w3.org/WAI/ARIA/apg/patterns/tabs/examples/tabs-automatic/" rel="noreferrer" target="_blank">tabs</a>, les <a href="https://www.w3.org/WAI/ARIA/apg/patterns/menubar/" rel="noreferrer" target="_blank">menus</a> et les <a href="https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/" rel="noreferrer" target="_blank">fen&ecirc;tres de dialogue</a> nécessitent cependant des interactions clavier plus avancées comme l'utilisation des flèches directionnelles, la gestion de la touche Escape ou encore la gestion du focus selon les directives officielles du W3C. Les utilisateur·rice·s qui dépendent de la navigation au clavier s’attendent à ces schémas spécifiques. S’en écarter provoque confusion et frustration. Plutôt que d’implémenter ces schémas depuis zéro, nous avons utilisé <a href="https://bits-ui.com/" rel="noreferrer" target="_blank">Bits UI</a>, une bibliothèque headless UI qui applique correctement ces directives d’accessibilité.</p>
<p>Au-delà des composants individuels, nous avons également implémenté des boucles de focus et une restauration du focus au niveau de l’application afin que les utilisateur·rice·s restent toujours orienté·e·s en passant d’une zone de l’interface du chat à une autre.</p>
<h2>Optimisation pour le zoom mobile</h2>
<p>Lors de tests utilisateur pour <a href="https://meinplatz.ch/" rel="noreferrer" target="_blank">meinplatz.ch</a> avec des personnes en situation de handicap, nous avons observé quelque chose de frappant: beaucoup naviguent sur les sites web sur mobile avec un zoom de 200 % ou plus et tiennent leur appareil à environ 10 cm de leurs yeux. Cette observation a mis en évidence une lacune critique dans la plupart des implémentations de chatbots.</p>
<p>La majorité des chatbots utilisent des éléments à position fixe: un champ de saisie en bas de l’écran et souvent un en-tête en haut. Lorsque les utilisateur·rice·s zooment fortement, ces éléments fixes peuvent occuper tout le viewport et rendre l’interface inutilisable. Malheureusement, les navigateurs ne permettent pas de détecter de manière fiable le niveau de zoom. Pour résoudre cela, nous utilisons l’Intersection Observer pour détecter lorsque l’en-tête ou le pied de page occupe plus d’espace que prévu. Dans ce cas, nous supprimons dynamiquement leur position fixe afin de rétablir l’utilisabilité.</p>
<figure class="video"><video autoplay controls loop muted playsinline><source src="https://www.liip.ch/media/pages/blog/making-liipgpt-accessible/343fac4583-1769071651/chatgpt-zoom.mp4" type="video/mp4"></video><figcaption>Des &eacute;l&eacute;ments &agrave; position fixe causent des probl&egrave;mes dans les vues fortement zoom&eacute;es.</figcaption></figure>
<figure class="video"><video autoplay controls loop muted playsinline><source src="https://www.liip.ch/media/pages/blog/making-liipgpt-accessible/6900992c5e-1769071651/liipgpt-zoom.mp4" type="video/mp4"></video><figcaption>La solution: r&eacute;tablir une position statique pour les &eacute;l&eacute;ments fixes lorsqu&rsquo;un zoom est d&eacute;tect&eacute;.</figcaption></figure>
<h2>Expérience avec les lecteurs d’écran</h2>
<p>L’accessibilité pour les lecteur·rice·s d’écran n’apparaît pas automatiquement, elle nécessite une conception attentive. Nous nous sommes concentré·e·s sur la fourniture d’un contexte clair grâce à une structure de page propre (landmarks et titres). Les utilisateur·rice·s comprennent ainsi toujours où iels se trouvent et ce qui se passe, tout en disposant de raccourcis vers les zones les plus importantes de l’application.</p>
<h4>Fournir du contexte</h4>
<p>Nous avons implémenté une structure d’outline complète avec des landmarks pour la navigation principale, les paramètres et les zones de saisie. Chaque message contient des titres et des labels corrects. De plus, nous avons ajouté après le champ de saisie du chat (en bas de page) un skip-link permettant aux utilisateur·rice·s de revenir rapidement en haut de la page.</p>
<h4>Défis avec les Web Components</h4>
<p>Travailler avec des Web Components a apporté ses propres défis. VoiceOver est particulièrement sensible à la manière dont les bibliothèques sont implémentées. Nous avons travaillé en étroite collaboration avec l’équipe Bits UI (qui réagit très rapidement aux rapports de bugs) et avons par exemple implémenté des portails locaux pour les menus déroulants afin d’éviter des problèmes de navigation avec VoiceOver.</p>
<h4>Gestion des annonces</h4>
<p>L’un des défis les plus complexes a été la gestion des annonces VoiceOver lorsque plusieurs événements se produisent simultanément. Comme la mise en file des annonces ne fonctionne pas de manière fiable, nous avons soigneusement séquencé les événements et regroupé les annonces liées. Par exemple, lorsqu’un·e utilisateur·rice clique sur « Tout sélectionner » dans une liste d’options, des annonces séparées seraient normalement déclenchées pour chaque option et se remplaceraient mutuellement. À la place, nous annulons ces annonces individuelles et les remplaçons par un seul message clair qui résume la situation (tous les éléments sélectionnés ou désélectionnés, retour à la sélection prédéfinie, etc.).</p>
<p>Comme le chat est une SPA sans rechargement de page, il était également essentiel d’annoncer tous les changements visibles uniquement visuellement, comme par exemple le changement entre mode clair et sombre ou le changement de langue.</p>
<h4>Flux du chat pour les lecteur·rice·s d’écran</h4>
<p>Nous avons conçu l’expérience du chat spécifiquement pour les utilisateur·rice·s de lecteur d’écran :</p>
<ul>
<li>Le champ de saisie contient à la fois un placeholder et un aria-label avec le titre de la page. Cela fournit du contexte lors du chargement de la page, car le champ est automatiquement focalisé et les utilisateur·rice·s peuvent ainsi ignorer le contenu initial.</li>
<li>Lorsqu’une réponse est générée, nous l’annonçons clairement afin de fournir le même retour qu’un indicateur de chargement visuel.</li>
<li>Dès qu’une réponse est prête, elle est lue sans formatage Markdown (pas d’italique, pas de liens, etc.) afin de garantir un flux de lecture naturel.</li>
<li>Après la lecture d’une réponse, nous indiquons que tu peux directement poser une nouvelle question ou naviguer vers les options du dernier message pour donner un feedback ou consulter les références. Nous ajoutons dynamiquement cette section interactive du dernier message à l’outline du document afin de créer un raccourci de navigation rapide.</li>
<li>L’historique du chat est structuré comme une série d’articles avec des labels afin que les conversations précédentes soient faciles à parcourir.</li>
</ul>
<figure class="video"><video autoplay controls loop muted playsinline><source src="https://www.liip.ch/media/pages/blog/making-liipgpt-accessible/912fd0d7cd-1769018708/screenreader.mp4" type="video/mp4"></video><figcaption>La solution: navigation dans le chatbot avec le lecteur d&rsquo;&eacute;cran VoiceOver sur macOS.</figcaption></figure>
<h2>Teste par toi-même</h2>
<p>Tu peux découvrir ces améliorations avec <a href="https://www.bs.ch/alva" rel="noreferrer" target="_blank">Alva</a>, le chatbot de l’administration du canton de Bâle-Ville. Essaie de naviguer avec <a href="https://www.google.com/search?q=how+to+navigate+a+website+with+voiceover" rel="noreferrer" target="_blank">VoiceOver (macOS)</a> ou <a href="https://www.google.com/search?q=how+to+navigate+a+website+with+nva+screen+reader" rel="noreferrer" target="_blank">NVA (Windows)</a>, d’utiliser uniquement ton clavier ou de zoomer fortement sur un appareil mobile.</p>
<h2>Un parcours continu</h2>
<p>Notre prochain objectif est d’intégrer des tests automatisés d’accessibilité dans notre pipeline CI. Comme mentionné précédemment, les scans automatisés ne détectent qu’environ 40 % des problèmes d’accessibilité. Cela signifie que nous devons continuer à planifier soigneusement chaque nouvelle fonctionnalité et à la tester manuellement. Rien ne remplace les tests humains lorsqu’il s’agit d’accessibilité. Les outils automatisés peuvent signaler des labels manquants ou des problèmes de contraste, mais ils ne peuvent pas déterminer si une interface est réellement utilisable pour quelqu’un qui navigue avec un lecteur d’écran ou uniquement au clavier.</p>
<p>L’accessibilité est un parcours continu, pas une destination. Nous nous engageons à rendre LiipGPT utilisable par tout le monde et continuerons à faire évoluer notre approche sur la base des retours issus de la pratique.</p>
<h2>Besoin d’aide pour l’accessibilité ?</h2>
<p>Nous proposons des audits d’accessibilité pour identifier et corriger les problèmes dans tes applications. Si tu souhaites améliorer l’accessibilité de ton produit, <a href="https://www.liip.ch/en/contact">contacte-nous</a>, nous serons ravi·e·s de t’aider.</p>]]></description>
    </item>
        <item>
      <title>Perspectives sur l&#8217;IA et l&#8217;open source pour les administrations publiques &#224; Drupal4Gov</title>
      <link>https://www.liip.ch/fr/blog/perspectives-sur-l-ia-et-l-open-source-pour-les-administrations-publiques-a-drupal4gov</link>
      <guid>https://www.liip.ch/fr/blog/perspectives-sur-l-ia-et-l-open-source-pour-les-administrations-publiques-a-drupal4gov</guid>
      <pubDate>Wed, 11 Mar 2026 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>La conférence Drupal4Gov était riche en présentations passionnantes dont tu trouveras ici mes moments favoris. J’y étais aussi pour présenter notre travail sur le projet Kanton Basel-Stadt / Alva / blökkli. Nous en avons déjà parlé, mais l’article est l’occasion de faire le point sur le projet et ses nouvelles fonctionnalités.</p>
<h2>GovNL: de plusieurs mois à quelques minutes pour créer des sites</h2>
<p>GovNL associe des composants Drupal open source et un design system ouvert pour faire fonctionner de nombreux sites du gouvernement néerlandais de manière accessible et évolutive. Le temps nécessaire pour créer un nouveau site passe alors <strong>d’environ trois mois à une dizaine de minutes</strong> seulement! Plutôt impressionnant, n’est-ce pas? C’est un excellent exemple de conception pensée pour la réutilisation à grande échelle.</p>
<h2>Commission européenne: la coordination est essentielle pour passer à l’échelle</h2>
<p>La Commission européenne gère déjà pas moins de <strong>770 sites</strong> et investit fortement dans l’écosystème Drupal. Ce qui m’a marqué, c’est l’importance qu’elle accorde à <strong>la coordination</strong>, soit s’assurer que le bon contenu est publié sur le bon canal à travers cet ensemble de sites. Les Open Source Program Offices (OSPO) ont été mis en place pour piloter les stratégies open source tant au niveau gouvernemental qu'au sein des organisations.</p>
<figure><img alt="" src="https://liip.rokka.io/www_inarticle_5/ac3271/drupal4gov2026-josef.jpg" srcset="https://liip.rokka.io/www_inarticle_5/o-dpr-2/ac3271/drupal4gov2026-josef.jpg 2x"></figure>
<h2>Site web du canton de Bâle-Ville et Alva: modèle pour les administrations publiques locales</h2>
<p>Juste avant midi, c’était à mon tour de présenter les <strong>différentes applications de l'IA</strong> que nous avons mis en place pour le <a href="https://www.liip.ch/fr/work/projects/basel-stadt">canton de B&acirc;le-Ville</a>. Avec la nouvelle version de bs.ch, le canton a établi de nouveaux standards avec un design centré sur les utilisateur·rices, un accès aux contenus thématiques plutôt que basés sur la structure administrative interne et Alva, le <strong>premier chatbot basé sur l’IA pour un canton</strong> suisse. La stack repose sur des composants open source et Liip a fortement contribué à l’open source dans le cadre de ce projet. Nous utilisons Drupal comme CMS, Nuxt/Vue, l’éditeur <a href="https://blokk.li/">bl&ouml;kkli</a> pour le frontend headless et Elasticsearch pour la recherche. Le contenu est produit par une équipe éditoriale transversale entre départements, suivant une stratégie de contenu claire.</p>
<h2>L’IA pour soutenir le public et les éditeur·rices du site</h2>
<p>Cette présentation était aussi l’occasion de partager des chiffres plus de 18 mois après la mise en ligne. Aujourd’hui, Alva traite <strong>plus de 10 000 questions par mois</strong>, avec environ <strong>1,36 question par conversation et une croissance de +44 % depuis Alva 2.0</strong>. Grâce aux intégrations API, le chatbot peut répondre à des questions en s’appuyant sur des informations en temps réel. Alva est également très utilisé par les collaborateur·rices internes du canton, en plus du grand public. Le chatbot affiche et vérifie toujours ses sources, un élément central pour instaurer la confiance. </p>
<p>Du côté de l’édition de contenu, blökkli travaille activement à simplifier les textes. Grâce à <strong>l’éditeur blökkli</strong> avec IA intégrée, les éditeur·rices peuvent désormais effectuer un audit de lisibilité, voir des propositions de simplification côte à côte et les accepter ou les adapter. Alva et les fonctionnalités d’IA sur bs.ch continuent d’être développées afin d’offrir aux éditeur·rices et aux citoyen·nes des technologies d’IA fiables.</p>
<h2>Des technologies IA au sein du gouvernement français</h2>
<p>Une autre présentation inspirante portait sur les cas d’usage de l’IA dans la plateforme Services Publics+ du gouvernement français. Avec plus de 140 000 expériences partagées et plus d’un million de réactions, le système utilise des technologies d’IA assistée pour aider les services de l’État à fournir des retours aux citoyen·nes. Ils utilisent notamment la transcription automatique de la parole (speech-to-text) et des résumés en temps réel comme technologies clés. Sacrés français:) </p>
<h2>L’UE fait plus que jamais confiance à l’open source</h2>
<p>L’Union européenne a introduit <strong>Website Evidence Collector</strong>, un outil open source qui analyse les sites web pour détecter des problèmes de sécurité. Il est publié sous licence <strong>EUPL</strong> (European Union Public Licence), ce qui met l’accent sur l’interopérabilité entre pays et licences et favorise la collaboration multilingue. Je me demande si la Suisse dispose d’un outil similaire.</p>
<p>Mais l’UE ne se contente pas de faire confiance à l’open source pour la sécurité. Avec Interoperable Europe, elle propose également un nouveau portail comprenant un <strong>Licensing Assistant</strong> très utile. Tu peux y <a href="https://interoperable-europe.ec.europa.eu/collection/eupl/solution/licensing-assistant/find-and-compare-software-licenses">trouver et comparer des licences logicielles</a> et utiliser un <a href="https://interoperable-europe.ec.europa.eu/collection/eupl/solution/licensing-assistant/compatibility-checker">outil de v&eacute;rification de compatibilit&eacute;</a> pour voir si différentes licences open source peuvent être combinées et s’il existe des complications juridiques.</p>
<h2>Utiliser l’open source ne suffit pas, il faut des champion·nes</h2>
<p>Enfin, <strong>Tiffany Farris</strong>, du cabinet de conseil stratégique <a href="https://www.palantir.net/">Palantir.net</a> (à ne pas confondre avec la controversée Palantir Technologies), a rappelé que <strong>l’utilisation de l’open source est une bonne chose mais n’est pas suffisante</strong>. Il faut <strong>des champion·nes</strong> dans les organisations qui mettent la contribution et la santé de l’écosystème à l’agenda. Concevoir pour la réutilisation devrait être un principe fondamental. Du point de vue américain, la commande publique reste un problème: l’usage de l’open source a augmenté, mais les mécanismes de soutien n’ont souvent pas suivi. Considérer l’open source comme « gratuit » peut conduire à attribuer des contrats à des fournisseurs qui présentent leur travail comme open source sans réellement soutenir un écosystème dynamique. Elle a enfin proposé des modifications concrètes des politiques de marchés publics dans l’esprit <strong>« public money, public code »</strong>, afin de mieux soutenir l’écosystème. Une conclusion vraiment inspirante pour une journée riche en apprentissages et en échanges.</p>
<p>Tu peux regarder <a href="https://www.youtube.com/playlist?list=PLNubpNMwP36QH5Y3RlbOiV4f9hjlrxCOo">la playlist</a> des présentations Drupal4Gov EU 2026 si tu souhaites approfondir les sujets abordés.</p>]]></description>
    </item>
        <item>
      <title>Web Components: The Good, the Bad, and the Ugly</title>
      <link>https://www.liip.ch/fr/blog/web-components-the-good-the-bad-and-the-ugly</link>
      <guid>https://www.liip.ch/fr/blog/web-components-the-good-the-bad-and-the-ugly</guid>
      <pubDate>Wed, 11 Mar 2026 00:00:00 +0100</pubDate>
      <description><![CDATA[<h1>Introduction</h1>
<p>We created a fully themeable chat UI that can be embedded in any website and has no effect on the parent page. <a href="https://www.bs.ch/alva">Kanton Basel-Stadts Alva</a> and <a href="https://ramms.ch/">RAMMS' Rocky AI</a> are instances of that UI.</p>
<p>This blog post will show you what we learned about creating web components that do not influence the parent page. Here are the good, the bad and the ugly when working with web components.</p>
<h1>The Good</h1>
<p>These are the good parts of web components. They will lay the foundation for why you might use them.</p>
<h2>Portability</h2>
<p>Every system that can handle HTML can handle web components. A simple tag and a script will integrate it into any web framework. It doesn't even need to be a JavaScript framework.</p>
<pre><code class="language-html">&lt;body&gt;
  &lt;your-webcomponent&gt;&lt;/your-webcomponent&gt;
  &lt;script src="path/to/your-webcomponent.js"&gt;&lt;/script&gt;
&lt;/body&gt;</code></pre>
<h2>Native Feel</h2>
<p>IFrames are another way to embed UI into a page, and they are arguably easier to use. But the main difference is that web components feel more native to the page, since they directly integrate into the parent page's layout. This means you can use transparency, intrinsic sizing (size based on the web component's contents), and seamless event communication with the parent page.</p>
<h2>Slots</h2>
<p>With slots you can provide content that will be added at a specified point inside your web component.</p>
<p>In our chat UI, we used a slot to let integrators provide a custom loading spinner. This spinner needs to be visible immediately, before the full theme loads asynchronously.</p>
<h2>Shadow DOM - Isolating Styles</h2>
<p>A robust way to ensure that your styles do not affect the parent page is to use the Shadow DOM. Shadow DOM is a web component feature to add a boundary for styles. Styles applied inside the Shadow DOM never apply to the parent page.</p>
<h3>Caveat: Inheritable CSS Properties</h3>
<p>There is one exception to the isolation where CSS properties of the parent page apply to the web component.</p>
<p>These are the properties that pierce through the boundary:</p>
<ul>
<li>Inheritable CSS properties like <code>color</code>, <code>font-family</code>, <code>line-height</code></li>
<li>CSS custom properties like <code>--my-var</code></li>
</ul>
<p>In practice, we have found it helps to fully specify the common properties like fonts and color on every element. That way you will never be surprised by different styles on integration.</p>
<h1>Vite</h1>
<p>For bundling web components, we can highly recommend Vite. There are a lot of neat tricks you can apply while bundling. Here are the Vite features we used for our web component.</p>
<h2>Inlining Assets</h2>
<p>Vite's <a href="https://vite.dev/guide/assets#explicit-inline-handling">explicit inline handling</a> feature allowed us to inline our external CSS files into the JS bundle.</p>
<pre><code class="language-ts">import cssContentString from "./index.css?inline";</code></pre>
<p>This feature will not only inline the raw content of the imported <code>index.css</code>. It will also resolve all CSS imports, apply PostCSS transforms, and even work with CSS preprocessors like SASS. While inlined CSS is not the most efficient for browsers to render, the benefit is that we can ship a single JS file.</p>
<h2>Library Mode</h2>
<p>The Vite <a href="https://vite.dev/guide/build#library-mode">library mode</a> provides you with fine-grained control of how the bundle should behave. To enable the library mode just add the <code>build.lib</code> option in your Vite config.</p>
<h1>The Bad</h1>
<p>Not everything about web components is great though. Here are the bad parts.</p>
<h2>SSR - Hard to Get Working</h2>
<p>Server-side rendering will almost certainly not work. The rest of the page can still be rendered server-side, but the web component will only show up as a <code>&lt;your-webcomponent&gt;&lt;/your-webcomponent&gt;</code> tag. Its contents will only be rendered in the browser.</p>
<p>There is one <a href="https://lit.dev/docs/ssr/overview/">experimental package by Lit Labs</a> that tries to solve this, but we never tried it.</p>
<h2>Tailwind - Not a Great Fit</h2>
<p>Tailwind feels like a natural choice for web components, but it does not play well with them.</p>
<p>The core issue is twofold. First, Tailwind ships its own CSS reset (called Preflight), which overrides default browser styles. When injected into a page that does not use Tailwind, it potentially breaks the page. Shadow DOM could isolate this reset, but Tailwind is fundamentally not designed to work inside a Shadow DOM. Here is the <a href="https://github.com/tailwindlabs/tailwindcss/discussions/1935">discussion</a> if you are interested.</p>
<p>There are some hacky workarounds, but we tried them and had no success getting them to work reliably.</p>
<p>Our recommendation is to only use Tailwind if you are guaranteed that the parent page also uses it, and then use web components without Shadow DOM.</p>
<h1>The Ugly</h1>
<h2>Verbose Web Components API</h2>
<p>The native web component API is verbose and hard to read. A simple counter component, for example, requires manually defining a class, attaching a shadow root, setting up <code>innerHTML</code>, and wiring event listeners in <code>connectedCallback</code>. This boilerplate adds up quickly. You can see examples of the API <a href="https://github.com/mdn/web-components-examples">here</a>.</p>
<p>Fortunately, web components make for a great compile target. <a href="https://svelte.dev/docs/svelte/custom-elements">Svelte</a> and <a href="https://vuejs.org/api/custom-elements.html#definecustomelement">Vue</a> directly support compiling to web components. <a href="https://blog.logrocket.com/working-custom-elements-react/">React</a> is a bit trickier, but totally doable as well. We used this approach for our chat UI, where the first iteration was built with React and the current one with Svelte.</p>
<h1>Weird Quirks</h1>
<p>Advanced web component features come with edge cases that no documentation warns you about. Even Svelte, which has excellent web component support, ships with a notable <a href="https://svelte.dev/docs/svelte/custom-elements#Caveats-and-limitations">list of caveats</a>.</p>
<p>We even hit an undocumented edge case with slots in Svelte: the bundle script must load after the component markup, or slotted content will not render. An ugly <a href="https://github.com/FalkZ/svelte-web-components-starter/blob/main/src/slot.svelte">wrapper for slots</a> fixes the problem, but quirks like this add up and slow you down.</p>
<h2>Font Loading - Not Working Inside Shadow DOM</h2>
<p>When authoring web components, you get into the habit of defining all stylesheet links etc. in the web component body. As you should, so they do not affect the parent page. But there is another annoying detail here: @font-face will not work when defined in the Shadow DOM. If your web component needs a custom font, you need to inject the font CSS into the parent page to make it work.</p>
<h1>Conclusion</h1>
<p>I do not want to end on this ugly note though. I really think there are cases where web components are the right choice, and in our case we would choose Svelte &amp; web components again.</p>
<p>To help you get started, here is a <a href="https://github.com/FalkZ/svelte-web-components-starter">Svelte starter template</a>.</p>]]></description>
    </item>
      </channel>
</rss>