Aller au contenu

⭐ Avis clientsGratuit · 0 NahnahPar NAHNAH AI

Galerie d’avis avec photos

Mur de vignettes : les photos envoyées par tes clients (ou un extrait de l’avis), qui s’ouvrent en grand avec l’avis complet dans une fenêtre accessible.

Aperçu en direct

Données de démonstration (produits, menus, textes d’exemple) : dans ta boutique, ce sont les tiennes.

Photos : Unsplash / Pexels (exemples de l’aperçu, jamais inclus dans le code).

Code à copier

Fichier complet sections/nahnah-avis-photos-galerie.liquid (Liquid, CSS et JS inclus).

{%- comment -%} NAHNAH AI · Galerie d'avis avec photos (bibliothèque Sections & effets). Uniquement des avis et photos réels, publiés avec l'accord du client. {%- endcomment -%}
{%- liquid
  assign nb_avis = 0
  assign total_notes = 0
  for block in section.blocks
    if block.settings.texte != blank
      assign nb_avis = nb_avis | plus: 1
      assign total_notes = total_notes | plus: block.settings.note
    endif
  endfor
  assign moyenne = 0
  if nb_avis > 0
    assign moyenne = total_notes | times: 1.0 | divided_by: nb_avis | round: 1
  endif
  assign moyenne_texte = moyenne | append: '' | replace: '.', ','
-%}
{%- if nb_avis > 0 -%}
<nn-avis-photos-galerie class="nn-avis-photos-galerie" style="--nn-mh: {{ section.settings.marge_haut }}px; --nn-mb: {{ section.settings.marge_bas }}px; --nn-fond: {{ section.settings.couleur_fond }}; --nn-texte: {{ section.settings.couleur_texte }}; --nn-accent: {{ section.settings.couleur_accent }};">
  <div class="nn-avis-photos-galerie__conteneur">
    <div class="nn-avis-photos-galerie__entete">
      {%- if section.settings.titre != blank -%}<h2 class="nn-avis-photos-galerie__titre">{{ section.settings.titre }}</h2>{%- endif -%}
      <p class="nn-avis-photos-galerie__resume"><span class="nn-avis-photos-galerie__etoiles" role="img" aria-label="Note : {{ moyenne_texte }} sur 5" style="--nn-pct: {{ moyenne | times: 20 }}%;"><span class="nn-avis-photos-galerie__etoiles-fond" aria-hidden="true">★★★★★</span><span class="nn-avis-photos-galerie__etoiles-plein" aria-hidden="true">★★★★★</span></span><span><strong>{{ moyenne_texte }}</strong> sur 5 · {{ nb_avis }} avis</span></p>
    </div>
    <ul class="nn-avis-photos-galerie__grille" role="list">
      {%- for block in section.blocks -%}
        {%- if block.settings.texte != blank -%}
          {%- assign id_modale = 'nn-apg-' | append: section.id | append: '-' | append: forloop.index -%}
          <li class="nn-avis-photos-galerie__item" {{ block.shopify_attributes }}>
            <button type="button" class="nn-avis-photos-galerie__vignette" data-nn-ouvrir="{{ id_modale }}" aria-haspopup="dialog">
              {%- if block.settings.photo != blank -%}
                {{ block.settings.photo | image_url: width: 500 | image_tag: loading: 'lazy', sizes: '(min-width: 990px) 25vw, 50vw', widths: '250, 500', class: 'nn-avis-photos-galerie__vignette-image', alt: '' }}
              {%- else -%}
                <span class="nn-avis-photos-galerie__vignette-texte">« {{ block.settings.texte | escape | truncate: 120 }} »</span>
              {%- endif -%}
              <span class="nn-avis-photos-galerie__vignette-pied">
                <span class="nn-avis-photos-galerie__etoiles" role="img" aria-label="Note : {{ block.settings.note }} sur 5" style="--nn-pct: {{ block.settings.note | times: 20 }}%;"><span class="nn-avis-photos-galerie__etoiles-fond" aria-hidden="true">★★★★★</span><span class="nn-avis-photos-galerie__etoiles-plein" aria-hidden="true">★★★★★</span></span>
                <span class="nn-avis-photos-galerie__vignette-nom">{{ block.settings.prenom | default: 'Client' | escape }}</span>
              </span>
              <span class="nn-avis-photos-galerie__cache">Lire l’avis complet</span>
            </button>
            <dialog class="nn-avis-photos-galerie__modale" id="{{ id_modale }}" aria-label="Avis de {{ block.settings.prenom | default: 'Client' | escape }}">
              <div class="nn-avis-photos-galerie__boite">
                <button type="button" class="nn-avis-photos-galerie__fermer" data-nn-fermer aria-label="Fermer l’avis"><svg aria-hidden="true" focusable="false" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M6 6l12 12M18 6 6 18"/></svg></button>
                {%- if block.settings.photo != blank -%}
                  {{ block.settings.photo | image_url: width: 1000 | image_tag: loading: 'lazy', sizes: '(min-width: 750px) 360px, 92vw', widths: '500, 750, 1000', class: 'nn-avis-photos-galerie__grande', alt: 'Photo envoyée par le client' }}
                {%- endif -%}
                <div class="nn-avis-photos-galerie__corps">
                  <span class="nn-avis-photos-galerie__etoiles" role="img" aria-label="Note : {{ block.settings.note }} sur 5" style="--nn-pct: {{ block.settings.note | times: 20 }}%;"><span class="nn-avis-photos-galerie__etoiles-fond" aria-hidden="true">★★★★★</span><span class="nn-avis-photos-galerie__etoiles-plein" aria-hidden="true">★★★★★</span></span>
                  <blockquote class="nn-avis-photos-galerie__texte"><p>{{ block.settings.texte | escape | newline_to_br }}</p></blockquote>
                  <footer class="nn-avis-photos-galerie__pied">
            <span class="nn-avis-photos-galerie__nom">{{ block.settings.prenom | default: 'Client' | escape }}</span>
            {%- if block.settings.date != blank -%}<span class="nn-avis-photos-galerie__date">{{ block.settings.date | escape }}</span>{%- endif -%}
            {%- if block.settings.achat_verifie -%}<span class="nn-avis-photos-galerie__verifie"><span aria-hidden="true">✓</span> Achat vérifié</span>{%- endif -%}
            {%- if block.settings.produit != blank -%}<a class="nn-avis-photos-galerie__produit" href="{{ block.settings.produit.url }}"><span class="nn-avis-photos-galerie__cache">Produit acheté : </span>{{ block.settings.produit.title | escape }}</a>{%- endif -%}
          </footer>
                </div>
              </div>
            </dialog>
          </li>
        {%- endif -%}
      {%- endfor -%}
    </ul>
    {%- if section.settings.mention != blank -%}<p class="nn-avis-photos-galerie__mention">{{ section.settings.mention | escape }}</p>{%- endif -%}
  </div>
</nn-avis-photos-galerie>
{%- elsif request.design_mode -%}
  <div class="nn-avis-photos-galerie__conteneur"><p class="nn-avis-photos-galerie__vide">Aucun avis affiché : ajoute de vrais avis avec « Ajouter un bloc » → Avis. La section reste invisible sur la boutique tant qu’aucun avis n’est saisi.</p></div>
{%- endif -%}

{% schema %}
{
  "name": "Galerie d’avis photos",
  "tag": "section",
  "class": "nn-section-avis-photos-galerie",
  "max_blocks": 40,
  "settings": [
    {
      "type": "inline_richtext",
      "id": "titre",
      "label": "Titre",
      "default": "Vos photos, vos avis"
    },
    {
      "type": "textarea",
      "id": "mention",
      "label": "Mention sur les avis (sous la liste)",
      "default": "Avis saisis par la boutique à partir des messages reçus de ses clients, sans modification. « Achat vérifié » : une commande correspondante a été retrouvée."
    },
    {
      "type": "header",
      "content": "Couleurs"
    },
    {
      "type": "color",
      "id": "couleur_fond",
      "label": "Fond",
      "default": "#111318"
    },
    {
      "type": "color",
      "id": "couleur_texte",
      "label": "Texte",
      "default": "#F2F5F9"
    },
    {
      "type": "color",
      "id": "couleur_accent",
      "label": "Accent",
      "default": "#F5C451"
    },
    {
      "type": "header",
      "content": "Espacement"
    },
    {
      "type": "range",
      "id": "marge_haut",
      "label": "Marge haute",
      "min": 0,
      "max": 120,
      "step": 4,
      "unit": "px",
      "default": 48
    },
    {
      "type": "range",
      "id": "marge_bas",
      "label": "Marge basse",
      "min": 0,
      "max": 120,
      "step": 4,
      "unit": "px",
      "default": 48
    }
  ],
  "blocks": [
    {
      "type": "avis",
      "name": "Avis",
      "settings": [
        {
          "type": "paragraph",
          "content": "Saisis uniquement un avis réellement reçu, sans le modifier. Inventer, acheter ou réécrire des avis est interdit (pratique commerciale trompeuse)."
        },
        {
          "type": "text",
          "id": "prenom",
          "label": "Prénom ou initiale du client"
        },
        {
          "type": "range",
          "id": "note",
          "label": "Note sur 5",
          "min": 1,
          "max": 5,
          "step": 1,
          "default": 5
        },
        {
          "type": "textarea",
          "id": "texte",
          "label": "Texte de l’avis (tel que reçu)"
        },
        {
          "type": "text",
          "id": "date",
          "label": "Date de l’avis (ex. 12 mars 2026)"
        },
        {
          "type": "image_picker",
          "id": "photo",
          "label": "Photo envoyée par le client (facultative)"
        },
        {
          "type": "product",
          "id": "produit",
          "label": "Produit acheté (facultatif)"
        },
        {
          "type": "checkbox",
          "id": "achat_verifie",
          "label": "Achat vérifié : coche seulement si tu as retrouvé la commande",
          "default": false
        }
      ]
    }
  ],
  "presets": [
    {
      "name": "Galerie d’avis photos"
    }
  ]
}
{% endschema %}

{% stylesheet %}
.nn-avis-photos-galerie {
  padding: var(--nn-mh) 0 var(--nn-mb);
  background: var(--nn-fond);
  color: var(--nn-texte);
}
.nn-avis-photos-galerie__conteneur {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 16px;
}
.nn-avis-photos-galerie__titre {
  margin: 0;
  font-size: clamp(24px, 4vw, 36px);
  line-height: 1.2;
  color: inherit;
}
.nn-avis-photos-galerie__cache {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.nn-avis-photos-galerie__vide {
  margin: 0;
  padding: 16px;
  border: 1px dashed currentColor;
  border-radius: 12px;
  font-size: 14px;
  opacity: 0.8;
}
nn-avis-photos-galerie { display: block; }
.nn-avis-photos-galerie__etoiles {
  position: relative;
  display: inline-block;
  flex: none;
  color: var(--nn-accent);
  font-size: var(--nn-taille-etoiles, 18px);
  line-height: 1;
  letter-spacing: 2px;
  white-space: nowrap;
}
.nn-avis-photos-galerie__etoiles-fond { opacity: 0.25; }
.nn-avis-photos-galerie__etoiles-plein {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: var(--nn-pct, 100%);
  overflow: hidden;
}
.nn-avis-photos-galerie__resume {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin: 0;
}
.nn-avis-photos-galerie__carte {
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
  padding: 20px;
  border: 1px solid color-mix(in srgb, var(--nn-texte) 10%, transparent);
  border-radius: 16px;
  background: color-mix(in srgb, var(--nn-texte) 4%, var(--nn-fond));
}
.nn-avis-photos-galerie__texte {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  overflow-wrap: anywhere;
}
.nn-avis-photos-galerie__texte p { margin: 0; }
.nn-avis-photos-galerie__photo {
  display: block;
  width: 96px;
  height: 96px;
  object-fit: cover;
  border-radius: 10px;
}
.nn-avis-photos-galerie__pied {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  margin-top: auto;
  font-size: 14px;
}
.nn-avis-photos-galerie__nom { font-weight: 700; }
.nn-avis-photos-galerie__date { opacity: 0.65; }
.nn-avis-photos-galerie__verifie {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, #1F8A5B 18%, transparent);
  font-size: 12px;
  font-weight: 600;
}
.nn-avis-photos-galerie__produit {
  flex-basis: 100%;
  color: inherit;
  font-size: 13px;
  opacity: 0.75;
  text-underline-offset: 3px;
}
.nn-avis-photos-galerie__produit:focus-visible {
  outline: 3px solid var(--nn-accent);
  outline-offset: 2px;
}
.nn-avis-photos-galerie__mention {
  max-width: 70ch;
  margin: 20px 0 0;
  font-size: 12px;
  opacity: 0.65;
}
.nn-avis-photos-galerie__entete {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 24px;
}
.nn-avis-photos-galerie__grille {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 750px) {
  .nn-avis-photos-galerie__grille { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
}
@media (min-width: 990px) {
  .nn-avis-photos-galerie__grille { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.nn-avis-photos-galerie__vignette {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  width: 100%;
  aspect-ratio: 1;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: 14px;
  background: color-mix(in srgb, var(--nn-texte) 8%, var(--nn-fond));
  color: #FFFFFF;
  font: inherit;
  text-align: start;
  cursor: pointer;
  isolation: isolate;
}
.nn-avis-photos-galerie__vignette:focus-visible {
  outline: 3px solid var(--nn-accent);
  outline-offset: 3px;
}
.nn-avis-photos-galerie__vignette-image {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease;
}
.nn-avis-photos-galerie__vignette::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0) 55%);
}
@media (hover: hover) {
  .nn-avis-photos-galerie__vignette:hover .nn-avis-photos-galerie__vignette-image { transform: scale(1.05); }
}
.nn-avis-photos-galerie__vignette-texte {
  position: absolute;
  inset: 0;
  padding: 16px;
  color: var(--nn-texte);
  font-size: 15px;
  line-height: 1.45;
  overflow: hidden;
}
.nn-avis-photos-galerie__vignette-pied {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px;
  --nn-taille-etoiles: 14px;
}
.nn-avis-photos-galerie__vignette-nom {
  font-size: 14px;
  font-weight: 700;
}
.nn-avis-photos-galerie__modale {
  width: min(760px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  padding: 0;
  border: 0;
  border-radius: 18px;
  background: var(--nn-fond);
  color: var(--nn-texte);
}
.nn-avis-photos-galerie__modale::backdrop { background: rgba(0, 0, 0, 0.7); }
.nn-avis-photos-galerie__boite {
  position: relative;
  display: grid;
  gap: 0;
}
@media (min-width: 750px) {
  .nn-avis-photos-galerie__boite:has(.nn-avis-photos-galerie__grande) { grid-template-columns: 360px minmax(0, 1fr); }
}
.nn-avis-photos-galerie__grande {
  display: block;
  width: 100%;
  height: 100%;
  max-height: 60vh;
  object-fit: cover;
}
.nn-avis-photos-galerie__corps {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 56px 24px 24px;
}
.nn-avis-photos-galerie__fermer {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--nn-fond);
  color: var(--nn-texte);
  cursor: pointer;
}
.nn-avis-photos-galerie__fermer svg {
  width: 22px;
  height: 22px;
}
.nn-avis-photos-galerie__fermer:focus-visible {
  outline: 3px solid var(--nn-accent);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .nn-avis-photos-galerie * {
    animation: none !important;
    transition: none !important;
  }
}
{% endstylesheet %}

{% javascript %}
(function () {
  // Ouverture de l'avis complet dans une fenêtre <dialog> native (Échap, focus piégé), fermeture par bouton ou fond
  function nnQuandPret(f) {
    if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", f, { once: true });
    else f();
  }
  if (!customElements.get("nn-avis-photos-galerie")) {
    customElements.define("nn-avis-photos-galerie", class extends HTMLElement {
      connectedCallback() {
        var moi = this;
        nnQuandPret(function () {
          if (moi.nnPret || !moi.isConnected) return;
          moi.nnPret = true;
          moi.demarrer();
        });
      }
      demarrer() {
        this.addEventListener("click", function (e) {
          var cible = e.target;
          var ouvrir = cible.closest && cible.closest("[data-nn-ouvrir]");
          if (ouvrir) {
            var modale = document.getElementById(ouvrir.getAttribute("data-nn-ouvrir"));
            if (modale && typeof modale.showModal === "function" && !modale.open) {
              modale.nnRetour = ouvrir;
              modale.showModal();
            }
            return;
          }
          var fermer = cible.closest && cible.closest("[data-nn-fermer]");
          if (fermer) {
            var d = fermer.closest("dialog");
            if (d) d.close();
            return;
          }
          if (cible.tagName === "DIALOG") cible.close();
        });
        Array.prototype.forEach.call(this.querySelectorAll("dialog"), function (d) {
          d.addEventListener("close", function () {
            if (d.nnRetour) d.nnRetour.focus();
          });
        });
      }
    });
  }
})();
{% endjavascript %}
Télécharger le fichier .liquid

Licence NAHNAH AI : utilisation libre dans tes boutiques (y compris commerciales), modification permise, revente de l’élément seul interdite.

Prompt à copier

À coller dans Claude ou ChatGPT avec le fichier téléchargé (ou le code copié) : l’assistant t’aide à l’installer et à l’adapter à ta marque.

Tu es un expert des thèmes Shopify Online Store 2.0. Aide-moi à installer puis à adapter à ma marque cet élément gratuit de la bibliothèque NAHNAH AI.

Élément : « Galerie d’avis avec photos » (Avis clients)
Description : Mur de vignettes : les photos envoyées par tes clients (ou un extrait de l’avis), qui s’ouvrent en grand avec l’avis complet dans une fenêtre accessible.
Page de l’élément (aperçu en direct) : https://ai.nahnah.shop/bibliotheque-shopify/avis-photos-galerie
Fichier : nahnah-avis-photos-galerie.liquid (bouton « Télécharger » de la page) ou le code copié avec le bouton « Copier » : je te le joins ou je le colle après ce message.
Emplacement dans le thème : sections/nahnah-avis-photos-galerie.liquid (Liquid, puis {% stylesheet %} et {% javascript %}, dans ce seul fichier).

Étapes d’installation :
1. Dans Shopify : Boutique en ligne → Thèmes → bouton « … » du thème → Modifier le code.
2. Dossier « sections » → « Ajouter une section » (ou « Nouveau fichier ») → nomme-la « nahnah-avis-photos-galerie ».
3. Efface le contenu proposé, colle le code de l’onglet Liquid (fichier complet), puis Enregistrer.
4. Ouvre Personnaliser → Ajouter une section → choisis-la, règle les textes et les couleurs, puis Enregistrer.

Ce que j’attends de toi :
- Guide-moi pas à pas dans Shopify : Boutique en ligne → Thèmes → « … » → Modifier le code → dossier sections → Ajouter une section, puis Personnaliser → Ajouter une section.
- Propose-moi d’adapter les couleurs, les textes et les liens à ma marque : demande d’abord mes couleurs (codes hexadécimaux), mon ton et mes liens.
- Garde le bloc {% schema %} et tous ses réglages (identifiants, types, presets) : je dois pouvoir tout régler ensuite dans l’éditeur de thème.
- Rends-moi le fichier complet modifié, prêt à coller, sans faux avis, fausse urgence ni chiffre inventé.

Si tu as le connecteur NAHNAH AI (MCP), récupère directement le code exact avec l’outil obtenir_code_element (id : avis-photos-galerie).

Installer dans ma boutique

En un clic, la section est ajoutée à un thème de ta boutique Shopify connectée (un thème non publié par défaut).

Chargement de tes boutiques…

Installer dans Shopify

  1. Dans Shopify : Boutique en ligne → Thèmes → bouton « … » du thème → Modifier le code.
  2. Dossier « sections » → « Ajouter une section » (ou « Nouveau fichier ») → nomme-la « nahnah-avis-photos-galerie ».
  3. Efface le contenu proposé, colle le code de l’onglet Liquid (fichier complet), puis Enregistrer.
  4. Ouvre Personnaliser → Ajouter une section → choisis-la, règle les textes et les couleurs, puis Enregistrer.

Installer via le MCP

Depuis Claude, Claude Code ou ChatGPT connecté à NAHNAH AI, demande : « Donne-moi le code de l’élément avis-photos-galerie de la bibliothèque NAHNAH AI et les étapes pour l’installer ». L’assistant récupère le code et les étapes (outil obtenir_code_element), gratuitement.

Boutique connectée à NAHNAH AI : l’assistant peut aussi l’installer directement (outil installer_element).

Connecter le MCP

Dans la même catégorie