Thème Shopify Acheter

Thème Shopify

Thème Shopify
Performance SEO

Un thème Shopify prêt à installer : plus de 50 sections et 250 optimisations déjà en place. Vous téléchargez le fichier, vous le posez sur votre boutique.

79€ Fichier du site
Aperçu du thème CASELORD

À qui s'adresse ce thème

Ce thème convient aux boutiques qui vendent des produits physiques avec un catalogue lisible : quelques dizaines à quelques milliers de références, des variantes, et un besoin de conversion plutôt que de vitrine.

Il est moins adapté aux catalogues de plusieurs dizaines de milliers de références, aux places de marché multi-vendeurs et aux tarifs négociés par client. Dans ces cas, nous partons sur un développement spécifique et nous le disons dès le premier échange.

config/settings_schema.json
[
  {
    "name": "Catalogue",
    "settings": [
      {
        "type": "range",
        "id": "produits_par_page",
        "label": "Produits par page",
        "min": 12, "max": 48, "step": 4,
        "default": 24
      },
      {
        "type": "checkbox",
        "id": "filtres_actifs",
        "label": "Filtres de collection",
        "default": true
      },
      {
        "type": "checkbox",
        "id": "recherche_predictive",
        "label": "Suggestions de recherche",
        "default": true
      }
    ]
  }
]

Fiche produit

Le changement de variante ne recharge pas la page : le thème écoute l'événement, met à jour le prix, l'image et le stock, puis réécrit l'URL pour que le lien reste partageable.

Les combinaisons indisponibles sont marquées plutôt que retirées, pour que le visiteur comprenne ce qui existe.

sections/product-variants.liquid
{%- for option in product.options_with_values -%}
  <fieldset class="variant" data-option="{{ option.position }}">
    <legend>{{ option.name }}</legend>

    {%- for value in option.values -%}
      {%- assign dispo = value.variant.available -%}
      <input
        type="radio"
        name="option-{{ option.position }}"
        value="{{ value | escape }}"
        {% if value.selected %}checked{% endif %}
        {% unless dispo %}data-epuise="true"{% endunless %}>
    {%- endfor -%}
  </fieldset>
{%- endfor -%}

Collections et recherche

Les filtres se déclarent dans Shopify, pas en dur dans le thème : vous en ajoutez ou en retirez sans toucher au code. Le thème parcourt ce que la boutique expose et construit les cases à cocher avec le décompte de produits.

L'état des filtres reste dans l'URL, donc une sélection se met en favori ou se partage telle quelle.

snippets/collection-filters.liquid
{%- for filtre in collection.filters -%}
  {%- case filtre.type -%}

    {%- when 'list' -%}
      <details class="filtre" open>
        <summary>{{ filtre.label }}</summary>
        {%- for valeur in filtre.values -%}
          <label {% if valeur.count == 0 %}data-vide="true"{% endif %}>
            <input type="checkbox"
                   name="{{ valeur.param_name }}"
                   value="{{ valeur.value }}"
                   {% if valeur.active %}checked{% endif %}>
            {{ valeur.label }} <span>({{ valeur.count }})</span>
          </label>
        {%- endfor -%}
      </details>

    {%- when 'price_range' -%}
      {%- render 'filtre-prix', filtre: filtre -%}

  {%- endcase -%}
{%- endfor -%}

Panier et commande

Le panier s'ouvre en tiroir sans quitter la page en cours. L'ajout se fait par l'API du panier, la réponse met à jour le compteur et le sous-total, et le visiteur continue à parcourir le catalogue.

La barre de livraison offerte se calcule sur le total réel, en centimes, pour éviter les arrondis qui faussent le seuil.

assets/panier.js
async function ajouterAuPanier(variantId, quantite = 1) {
  const reponse = await fetch('/cart/add.js', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      items: [{ id: variantId, quantity: quantite }]
    })
  });

  if (!reponse.ok) {
    const erreur = await reponse.json();
    return afficherErreur(erreur.description);
  }

  const panier = await (await fetch('/cart.js')).json();

  majCompteur(panier.item_count);
  majFranchisePort(panier.total_price);
  ouvrirTiroir();
}

Personnalisation

Chaque section expose ses réglages dans un schéma JSON. C'est ce fichier qui fait apparaître les champs dans l'éditeur Shopify : vous modifiez le contenu et la mise en forme sans ouvrir un seul fichier.

Ajouter un réglage revient à ajouter une entrée dans ce schéma.

sections/hero.liquid
{% schema %}
{
  "name": "Bannière",
  "settings": [
    { "type": "image_picker", "id": "image",  "label": "Image de fond" },
    { "type": "text",         "id": "titre",  "label": "Titre" },
    { "type": "richtext",     "id": "texte",  "label": "Texte" },
    {
      "type": "select",
      "id": "hauteur",
      "label": "Hauteur",
      "options": [
        { "value": "petite", "label": "Petite" },
        { "value": "moyenne", "label": "Moyenne" },
        { "value": "plein",  "label": "Plein écran" }
      ],
      "default": "moyenne"
    },
    { "type": "color_scheme", "id": "palette", "label": "Palette" }
  ],
  "presets": [{ "name": "Bannière" }]
}
{% endschema %}

Performance

Chaque image est déclarée avec ses dimensions et une liste de largeurs. Le navigateur choisit le fichier adapté à l'écran au lieu de télécharger la version la plus grande.

L'image principale de la fiche est chargée en priorité ; tout le reste attend d'approcher de l'écran.

snippets/image.liquid
{%- assign largeurs = '400,600,800,1200,1600' -%}

<img
  src="{{ image | image_url: width: 800 }}"
  srcset="{%- for l in largeurs -%}
            {{ image | image_url: width: l }} {{ l }}w
            {%- unless forloop.last %}, {% endunless -%}
          {%- endfor -%}"
  sizes="(min-width: 990px) 50vw, 100vw"
  width="{{ image.width }}"
  height="{{ image.height }}"
  alt="{{ image.alt | escape }}"
  {% if prioritaire %}fetchpriority="high"{% else %}loading="lazy"{% endif %}>

Référencement

Les données structurées sont générées à partir du produit réel, pas saisies à la main : prix, devise, disponibilité et note moyenne suivent ce que contient la boutique.

C'est ce balisage qui permet à Google d'afficher le prix et les étoiles sous votre lien.

snippets/schema-produit.liquid
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": {{ product.title | json }},
  "image": {{ product.featured_image | image_url: width: 1200 | json }},
  "description": {{ product.description | strip_html | truncate: 300 | json }},
  "sku": {{ product.selected_or_first_available_variant.sku | json }},
  "brand": {
    "@type": "Brand",
    "name": {{ product.vendor | json }}
  },
  "offers": {
    "@type": "Offer",
    "price": {{ product.price | divided_by: 100.0 | json }},
    "priceCurrency": {{ cart.currency.iso_code | json }},
    "availability": "https://schema.org/{% if product.available %}InStock{% else %}OutOfStock{% endif %}",
    "url": {{ request.origin | append: product.url | json }}
  }
}
</script>

Installation et mise en ligne

Le thème est installé en publication différée : votre boutique actuelle continue de tourner pendant que nous travaillons sur la nouvelle version. Vous la voyez avancer par un lien d'aperçu.

À la mise en ligne, les anciennes adresses sont redirigées une à une pour ne perdre aucune position acquise.

redirections.csv
Redirect from,Redirect to
/collections/sacs-cuir,/collections/maroquinerie
/produits/sac-porte-epaule,/products/sac-porte-epaule
/pages/a-propos,/pages/notre-histoire
/blog/actualites,/blogs/journal
/collections/all?sort=new,/collections/nouveautes

Limites à connaître

Le tunnel de paiement appartient à Shopify et n'est pas modifiable hors offre Plus. Les applications tierces sont le premier facteur de ralentissement d'une boutique : chaque ajout se pèse.

Les tarifs différenciés par client relèvent des fonctions B2B, disponibles selon votre offre Shopify. Un catalogue de plusieurs dizaines de milliers de références demande un moteur de recherche dédié, en complément du thème.

layout/theme.liquid
{%- comment -%}
  Les applications s'injectent ici. Chacune ajoute ses propres
  requêtes : on mesure avant et après, et on retire ce qui coûte
  plus qu'il ne rapporte.
{%- endcomment -%}

{{ content_for_header }}

{%- if settings.mesure_active -%}
  {%- render 'mesure-performance' -%}
{%- endif -%}

Discutons de votre boutique

Nous installons le thème, le paramétrons à votre catalogue et vous montrons comment le faire vivre. Dites-nous où vous en êtes.

Offre premier achat

Offre appliquée