[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"theme-db":3,"$fMwOAAEj4G2yEFBUwqtQFAYznzGBdWf9FAWmii-uvBVI":22,"$fKnz2vuX4bZz1LbUTiuFsvSZ3e07l5_5fqNYp4Tzdhi8":66,"megamenu":147,"header-db":204,"footer-db":217,"$f7aDuCly-OfYf-d-DMkFE8c6nA11u5khdQQIQJWgNyKw":233},{"theme":4},{"colors":5,"typography":13,"ui":17,"defaultColorMode":21},{"primary":6,"secondary":7,"background":8,"foreground":9,"muted":10,"headerBg":11,"footerBg":12,"topBarBg":9,"topBarText":11},"#4F46E5","#0D9488","#F9FAFB","#111827","#6B7280","#ffffff","#020617",{"fontFamily":14,"fontUrl":15,"baseFontSize":16},"Inter, system-ui, sans-serif","https:\u002F\u002Ffonts.googleapis.com\u002Fcss2?family=Inter:wght@400;500;600;700&family=Playfair+Display:ital,wght@0,400;0,700;0,800;0,900;1,400;1,700&display=swap","16px",{"borderRadius":18,"contentWidth":19,"shadow":20},"lg","7xl",true,"light",{"title":23,"slug":24,"metaDescription":25,"category":26,"tags":27,"difficulty":33,"psVersions":34,"content":38,"faq":39,"tldr":61,"readingTime":62,"generatedAt":63,"publishDate":63,"relatedArticles":64,"sourceCategory":65},"Multiboutique PrestaShop : afficher les produits d'un autre site avec Homefeatured","multiboutique-homefeatured-produits-cross-site-prestashop","Comment afficher les produits d'une boutique B sur la page d'accueil d'une boutique A en multiboutique PrestaShop. Guide complet avec code Smarty et SQL.","multiboutique",[26,28,29,30,31,32],"homefeatured","smarty","cross-selling","produits","multisite","avance",[35,36,37],"1.6","1.7","8.x","\u003Ch2>Le défi du cross-site en multiboutique PrestaShop\u003C\u002Fh2>\n\u003Cp>Le mode multiboutique de PrestaShop permet de gérer plusieurs sites e-commerce depuis un seul back-office. Mais une limitation revient régulièrement : \u003Cstrong>comment afficher sur la boutique A les produits qui appartiennent à la boutique B ?\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>Par défaut, le module Homefeatured (remplacé par \u003Ccode>ps_featuredproducts\u003C\u002Fcode> depuis PrestaShop 1.7) ne récupère que les produits associés à la boutique courante. Les requêtes SQL internes filtrent systématiquement par \u003Ccode>id_shop\u003C\u002Fcode>, ce qui empêche tout affichage cross-site natif.\u003C\u002Fp>\n\u003Cp>Ce guide détaille deux approches pour contourner cette limitation, de la plus simple à la plus robuste.\u003C\u002Fp>\n\u003Ch2>Comprendre le filtrage multiboutique dans PrestaShop\u003C\u002Fh2>\n\u003Cp>Avant de modifier quoi que ce soit, il faut comprendre comment PrestaShop isole les données par boutique.\u003C\u002Fp>\n\u003Ch3>Le mécanisme Shop::addSqlRestriction\u003C\u002Fh3>\n\u003Cp>Chaque requête SQL générée par PrestaShop passe par la méthode \u003Ccode>Shop::addSqlRestriction()\u003C\u002Fcode>. Cette méthode ajoute automatiquement une clause \u003Ccode>WHERE\u003C\u002Fcode> qui filtre par \u003Ccode>id_shop\u003C\u002Fcode> ou par \u003Ccode>id_shop_group\u003C\u002Fcode> selon le contexte.\u003C\u002Fp>\n\u003Cp>Dans le module Homefeatured (PS 1.6) ou ps_featuredproducts (PS 1.7+), la requête de récupération des produits ressemble à :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">\nSELECT p.id_product, pl.name, pl.link_rewrite, i.id_image\nFROM ps_product p\nINNER JOIN ps_product_shop ps ON (ps.id_product = p.id_product AND ps.id_shop = {id_shop_courante})\nINNER JOIN ps_product_lang pl ON (pl.id_product = p.id_product AND pl.id_shop = {id_shop_courante})\nWHERE p.active = 1\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Le filtre \u003Ccode>ps.id_shop = {id_shop_courante}\u003C\u002Fcode> est la raison pour laquelle les produits de la boutique B n'apparaissent jamais sur la boutique A.\u003C\u002Fp>\n\u003Ch2>Approche 1 : partager les produits entre boutiques (la plus simple)\u003C\u002Fh2>\n\u003Cp>La méthode la plus directe consiste à \u003Cstrong>associer les produits aux deux boutiques\u003C\u002Fstrong> depuis le back-office, puis à personnaliser le template pour rediriger les liens vers le bon domaine.\u003C\u002Fp>\n\u003Ch3>Étape 1 — Associer les produits aux deux boutiques\u003C\u002Fh3>\n\u003Cp>Depuis le back-office PrestaShop :\u003C\u002Fp>\n\u003Col>\n\u003Cli>Passez en contexte **\"Toutes les boutiques\"** via le sélecteur multiboutique\u003C\u002Fli>\n\u003Cli>Ouvrez chaque produit concerné\u003C\u002Fli>\n\u003Cli>Dans l'onglet **Associations**, cochez les deux boutiques\u003C\u002Fli>\n\u003Cli>Sauvegardez\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Pour une association en masse, utilisez cette requête SQL (à adapter) :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-sql\">\n-- Associer tous les produits de la boutique 2 à la boutique 1\nINSERT IGNORE INTO ps_product_shop (id_product, id_shop, id_category_default, id_tax_rules_group, \n  on_sale, online_only, ecotax, minimal_quantity, price, wholesale_price, unity, unit_price_ratio,\n  additional_shipping_cost, customizable, uploadable_files, text_fields, active, redirect_type,\n  available_for_order, available_date, show_condition, condition, show_price, indexed, visibility,\n  cache_default_attribute, advanced_stock_management, date_add, date_upd, pack_stock_type)\nSELECT id_product, 1, id_category_default, id_tax_rules_group,\n  on_sale, online_only, ecotax, minimal_quantity, price, wholesale_price, unity, unit_price_ratio,\n  additional_shipping_cost, customizable, uploadable_files, text_fields, active, redirect_type,\n  available_for_order, available_date, show_condition, condition, show_price, indexed, visibility,\n  cache_default_attribute, advanced_stock_management, date_add, date_upd, pack_stock_type\nFROM ps_product_shop\nWHERE id_shop = 2;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cblockquote>\u003Cp>\u003Cstrong>Attention :\u003C\u002Fstrong> n'oubliez pas de dupliquer également les entrées dans \u003Ccode>ps_product_lang\u003C\u002Fcode> pour la boutique cible, sinon les noms et descriptions seront vides.\u003C\u002Fp>\u003C\u002Fblockquote>\n\u003Ch3>Étape 2 — Personnaliser le template pour les liens cross-site\u003C\u002Fh3>\n\u003Cp>Une fois les produits visibles sur les deux boutiques, le problème suivant est que \u003Cstrong>les liens pointent vers le domaine de la boutique courante\u003C\u002Fstrong> au lieu de la boutique d'origine.\u003C\u002Fp>\n\u003Cp>Pour corriger cela, il faut surcharger le template de la liste produits pour réécrire les URLs.\u003C\u002Fp>\n\u003Cp>#### Sur PrestaShop 1.6 (Smarty)\u003C\u002Fp>\n\u003Cp>Créez un fichier \u003Ccode>home-product-list.tpl\u003C\u002Fcode> dans votre thème :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-smarty\">\n{foreach from=$products item=product name=homeProducts}\n&lt;div class=\"product-container\"&gt;\n    &lt;div class=\"product-image-container\"&gt;\n        {* Déterminer le domaine cible selon la boutique d'origine du produit *}\n        {assign var='target_domain' value='https:\u002F\u002Fwww.boutique-b.com'}\n        \n        &lt;a class=\"product_img_link\" \n           href=\"{$target_domain}\u002F{$product.link_rewrite|escape:'html':'UTF-8'}-{$product.id_product}.html\" \n           title=\"{$product.name|escape:'html':'UTF-8'}\"&gt;\n            &lt;img class=\"img-responsive\" \n                 src=\"{$link-&gt;getImageLink($product.link_rewrite, $product.id_image, 'home_default')}\" \n                 alt=\"{$product.name|escape:'html':'UTF-8'}\" \u002F&gt;\n        &lt;\u002Fa&gt;\n    &lt;\u002Fdiv&gt;\n    &lt;div class=\"product-meta\"&gt;\n        &lt;h5&gt;\n            &lt;a href=\"{$target_domain}\u002F{$product.link_rewrite|escape:'html':'UTF-8'}-{$product.id_product}.html\"&gt;\n                {$product.name|truncate:45:'...'|escape:'html':'UTF-8'}\n            &lt;\u002Fa&gt;\n        &lt;\u002Fh5&gt;\n        &lt;span class=\"price\"&gt;{$product.price|escape:'html':'UTF-8'}&lt;\u002Fspan&gt;\n    &lt;\u002Fdiv&gt;\n&lt;\u002Fdiv&gt;\n{\u002Fforeach}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Puis dans \u003Ccode>homefeatured.tpl\u003C\u002Fcode>, remplacez l'appel au template standard :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-smarty\">\n{if isset($products) && $products}\n    {include file=\"$tpl_dir.\u002Fhome-product-list.tpl\" class='homefeatured tab-pane' id='homefeatured'}\n{else}\n    &lt;ul id=\"homefeatured\" class=\"homefeatured tab-pane\"&gt;\n        &lt;li class=\"alert alert-info\"&gt;{l s='No featured products at this time.' mod='homefeatured'}&lt;\u002Fli&gt;\n    &lt;\u002Ful&gt;\n{\u002Fif}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>#### Sur PrestaShop 1.7+ \u002F 8.x\u003C\u002Fp>\n\u003Cp>Le module \u003Ccode>ps_featuredproducts\u003C\u002Fcode> utilise un système de templates différent. Surchargez le template dans votre thème :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-\">\nthemes\u002Fvotre-theme\u002Fmodules\u002Fps_featuredproducts\u002Fviews\u002Ftemplates\u002Fhook\u002Fps_featuredproducts.tpl\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>La logique reste identique : intercepter le lien produit et remplacer le domaine.\u003C\u002Fp>\n\u003Ch3>Limites de cette approche\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>**Maintenance double** : chaque modification de produit doit être répétée ou synchronisée\u003C\u002Fli>\n\u003Cli>**URLs en dur** : le domaine cible est codé dans le template\u003C\u002Fli>\n\u003Cli>**Stocks partagés** : le stock est commun aux deux boutiques (sauf configuration avancée)\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>Approche 2 : requête SQL cross-shop dans un module personnalisé (recommandé)\u003C\u002Fh2>\n\u003Cp>Pour une solution plus propre et maintenable, la meilleure approche consiste à créer un module qui effectue directement une requête cross-shop.\u003C\u002Fp>\n\u003Ch3>Le principe\u003C\u002Fh3>\n\u003Cp>Au lieu de laisser PrestaShop filtrer par boutique, on écrit une requête qui cible explicitement la boutique source :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-php\">\n&lt;?php\n\u002F**\n * Module d'affichage cross-boutique pour la page d'accueil\n * Compatible PrestaShop 1.7 \u002F 8.x\n *\u002F\nclass AcCrossShopFeatured extends Module\n{\n    public function __construct()\n    {\n        $this-&gt;name = 'ac_crossshopfeatured';\n        $this-&gt;version = '1.0.0';\n        $this-&gt;author = 'Alexandre Carette';\n        parent::__construct();\n        $this-&gt;displayName = $this-&gt;l('Cross-Shop Featured Products');\n    }\n\n    public function hookDisplayHome($params)\n    {\n        $targetShopId = (int) Configuration::get('AC_CROSSSHOP_TARGET_ID');\n        $categoryId = (int) Configuration::get('AC_CROSSSHOP_CATEGORY_ID');\n        $limit = (int) Configuration::get('AC_CROSSSHOP_LIMIT') ?: 8;\n        $idLang = (int) $this-&gt;context-&gt;language-&gt;id;\n\n        $sql = new DbQuery();\n        $sql-&gt;select('p.id_product, pl.name, pl.link_rewrite, pl.description_short');\n        $sql-&gt;select('ps.price, i.id_image');\n        $sql-&gt;from('product', 'p');\n        $sql-&gt;innerJoin('product_shop', 'ps', 'ps.id_product = p.id_product AND ps.id_shop = ' . $targetShopId);\n        $sql-&gt;innerJoin('product_lang', 'pl', 'pl.id_product = p.id_product AND pl.id_lang = ' . $idLang . ' AND pl.id_shop = ' . $targetShopId);\n        $sql-&gt;leftJoin('image_shop', 'i', 'i.id_product = p.id_product AND i.id_shop = ' . $targetShopId . ' AND i.cover = 1');\n        \n        if ($categoryId) {\n            $sql-&gt;innerJoin('category_product', 'cp', 'cp.id_product = p.id_product AND cp.id_category = ' . $categoryId);\n        }\n\n        $sql-&gt;where('ps.active = 1');\n        $sql-&gt;where('ps.visibility IN (\"both\", \"catalog\")');\n        $sql-&gt;orderBy('p.date_add DESC');\n        $sql-&gt;limit($limit);\n\n        $products = Db::getInstance()-&gt;executeS($sql);\n\n        \u002F\u002F Récupérer le domaine de la boutique cible\n        $targetShopUrl = $this-&gt;getShopUrl($targetShopId);\n\n        $this-&gt;context-&gt;smarty-&gt;assign([\n            'crossProducts' =&gt; $products,\n            'targetShopUrl' =&gt; $targetShopUrl,\n        ]);\n\n        return $this-&gt;display(__FILE__, 'views\u002Ftemplates\u002Fhook\u002Fcrossshop-featured.tpl');\n    }\n\n    private function getShopUrl(int $shopId): string\n    {\n        $shop = new Shop($shopId);\n        $ssl = Configuration::get('PS_SSL_ENABLED') ? 'https:\u002F\u002F' : 'http:\u002F\u002F';\n        return $ssl . $shop-&gt;domain_ssl;\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Le template associé\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-smarty\">\n{if $crossProducts && count($crossProducts) &gt; 0}\n&lt;section class=\"featured-products cross-shop-products\"&gt;\n    &lt;h2&gt;{l s='Sélection de notre boutique partenaire' mod='ac_crossshopfeatured'}&lt;\u002Fh2&gt;\n    &lt;div class=\"products-grid\"&gt;\n        {foreach from=$crossProducts item=product}\n        &lt;article class=\"product-miniature\"&gt;\n            &lt;a href=\"{$targetShopUrl}\u002F{$product.link_rewrite}-{$product.id_product}.html\"&gt;\n                &lt;img src=\"{$link-&gt;getImageLink($product.link_rewrite, $product.id_image, 'home_default')}\" \n                     alt=\"{$product.name|escape:'html':'UTF-8'}\" loading=\"lazy\" \u002F&gt;\n            &lt;\u002Fa&gt;\n            &lt;h3&gt;\n                &lt;a href=\"{$targetShopUrl}\u002F{$product.link_rewrite}-{$product.id_product}.html\"&gt;\n                    {$product.name|escape:'html':'UTF-8'}\n                &lt;\u002Fa&gt;\n            &lt;\u002Fh3&gt;\n            &lt;span class=\"price\"&gt;{Tools::displayPrice($product.price)}&lt;\u002Fspan&gt;\n        &lt;\u002Farticle&gt;\n        {\u002Fforeach}\n    &lt;\u002Fdiv&gt;\n&lt;\u002Fsection&gt;\n{\u002Fif}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>Construction correcte des URLs cross-boutique\u003C\u002Fh2>\n\u003Cp>L'un des pièges majeurs du cross-site multiboutique est la \u003Cstrong>génération des URLs produit\u003C\u002Fstrong>. Par défaut, \u003Ccode>$link->getProductLink()\u003C\u002Fcode> génère toujours une URL relative à la boutique courante.\u003C\u002Fp>\n\u003Ch3>Le problème\u003C\u002Fh3>\n\u003Cp>Si vous êtes sur \u003Ccode>boutique-a.com\u003C\u002Fcode> et affichez un produit de \u003Ccode>boutique-b.com\u003C\u002Fcode>, l'appel standard :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-php\">\n$link-&gt;getProductLink($product);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>…retournera \u003Ccode>https:\u002F\u002Fboutique-a.com\u002Fproduit-1.html\u003C\u002Fcode> au lieu de \u003Ccode>https:\u002F\u002Fboutique-b.com\u002Fproduit-1.html\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch3>La solution propre en PHP\u003C\u002Fh3>\n\u003Cp>Utilisez le contexte de la boutique cible temporairement :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-php\">\n\u002F\u002F Sauvegarder le contexte actuel\n$currentShopId = Shop::getContextShopID();\n\n\u002F\u002F Basculer vers la boutique cible\nShop::setContext(Shop::CONTEXT_SHOP, $targetShopId);\n$targetLink = new Link();\n$productUrl = $targetLink-&gt;getProductLink(\n    $product['id_product'],\n    $product['link_rewrite'],\n    null,\n    null,\n    $idLang,\n    $targetShopId\n);\n\n\u002F\u002F Restaurer le contexte original\nShop::setContext(Shop::CONTEXT_SHOP, $currentShopId);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Cette méthode est \u003Cstrong>la seule qui respecte les règles de réécriture d'URL\u003C\u002Fstrong> configurées pour chaque boutique (URL simplifiée ou non, préfixe de langue, etc.).\u003C\u002Fp>\n\u003Ch2>Gestion des images en cross-boutique\u003C\u002Fh2>\n\u003Cp>Les images produit sont un autre point de vigilance. En multiboutique, les images sont partagées physiquement sur le serveur mais leur association est filtrée par \u003Ccode>id_shop\u003C\u002Fcode> dans la table \u003Ccode>ps_image_shop\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>Si vous avez associé vos produits aux deux boutiques (approche 1), les images sont déjà accessibles. Sinon, vous devrez construire manuellement l'URL de l'image :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-php\">\n$imageUrl = _PS_BASE_URL_ . '\u002Fimg\u002Fp\u002F' \n    . implode('\u002F', str_split((string) $idImage)) \n    . '\u002F' . $idImage . '-home_default.jpg';\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Ou plus proprement via le \u003Ccode>Link\u003C\u002Fcode> object :\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-php\">\n$imageUrl = $link-&gt;getImageLink($product['link_rewrite'], $product['id_image'], 'home_default');\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>Bonnes pratiques pour le multiboutique cross-site\u003C\u002Fh2>\n\u003Ch3>Performance\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>**Cachez les résultats** : les requêtes cross-shop ajoutent des jointures supplémentaires. Utilisez le cache PrestaShop (`Cache::store()`) avec un TTL de 1 heure minimum\u003C\u002Fli>\n\u003Cli>**Indexez correctement** : vérifiez que `ps_product_shop` a bien un index composite sur `(id_product, id_shop)`\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>SEO\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>**Canonical URLs** : assurez-vous que chaque produit a une URL canonique qui pointe vers sa boutique principale pour éviter le contenu dupliqué\u003C\u002Fli>\n\u003Cli>**Attribut `rel=\"nofollow\"`** : sur les liens cross-site de la page d'accueil, envisagez d'ajouter `rel=\"nofollow\"` si vous voulez que le jus SEO reste sur chaque domaine respectif\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>Maintenance\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>**Documentez la configuration** : notez quelle boutique est la source et quelle est la cible\u003C\u002Fli>\n\u003Cli>**Testez les deux sens** : vérifiez les URLs générées depuis chaque boutique\u003C\u002Fli>\n\u003Cli>**Surveillez les 404** : après une mise à jour de produit, vérifiez que les liens cross-site restent valides\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>Conclusion\u003C\u002Fh2>\n\u003Cp>L'affichage cross-boutique dans PrestaShop multiboutique n'est pas supporté nativement, mais reste tout à fait réalisable. L'approche la plus maintenable est le module personnalisé avec requête SQL ciblée, car elle offre un contrôle total sur les données affichées et les URLs générées. Pour des besoins ponctuels, le partage de produits avec surcharge de template reste une solution rapide et fonctionnelle.\u003C\u002Fp>",[40,43,46,49,52,55,58],{"q":41,"a":42},"Comment afficher les produits d'une autre boutique en multiboutique PrestaShop ?","Deux approches existent : soit associer les produits aux deux boutiques et personnaliser le template pour corriger les liens, soit créer un module personnalisé qui effectue une requête SQL ciblant explicitement la boutique source via son id_shop, sans passer par le filtrage automatique de Shop::addSqlRestriction().",{"q":44,"a":45},"Pourquoi les liens produit pointent vers le mauvais domaine en multiboutique ?","Par défaut, la méthode getProductLink() de PrestaShop génère les URLs dans le contexte de la boutique courante. Pour obtenir un lien vers une autre boutique, il faut temporairement basculer le contexte shop avec Shop::setContext() avant de générer le lien, puis restaurer le contexte original.",{"q":47,"a":48},"Le module ps_featuredproducts supporte-t-il le cross-boutique sur PrestaShop 8 ?","Non, ps_featuredproducts (successeur de homefeatured) filtre toujours les produits par boutique courante. Pour un affichage cross-site, il faut soit surcharger le module, soit développer un module dédié qui contourne le filtrage par id_shop dans ses requêtes SQL.",{"q":50,"a":51},"Comment partager les images produit entre deux boutiques PrestaShop ?","Les fichiers images sont partagés physiquement sur le serveur, mais leur visibilité est contrôlée par la table ps_image_shop. En associant un produit à plusieurs boutiques, les entrées dans ps_image_shop sont automatiquement créées. Pour un module custom, vous pouvez construire l'URL d'image manuellement ou utiliser la méthode Link::getImageLink().",{"q":53,"a":54},"Comment éviter le contenu dupliqué SEO en multiboutique avec des produits partagés ?","Définissez une URL canonique pointant vers la boutique principale du produit via la balise link rel=\"canonical\". Sur les liens cross-site affichés en page d'accueil, ajoutez éventuellement un attribut rel=\"nofollow\" pour maîtriser la distribution du jus SEO entre vos domaines.",{"q":56,"a":57},"Est-il possible d'afficher une catégorie spécifique d'une autre boutique sur la page d'accueil ?","Oui, en utilisant un module personnalisé. Il suffit d'ajouter une jointure sur ps_category_product dans la requête SQL cross-shop en filtrant par l'id_category souhaitée, tout en ciblant l'id_shop de la boutique source. Cette approche permet un contrôle fin sur les produits affichés.",{"q":59,"a":60},"Faut-il dupliquer les stocks quand on partage des produits entre boutiques PrestaShop ?","Par défaut, PrestaShop partage le stock entre les boutiques associées au même produit. Si vous avez besoin de stocks indépendants par boutique, activez la gestion avancée des stocks dans les paramètres de chaque boutique. Avec l'approche module custom (requête SQL directe), le stock n'est pas impacté puisque vous ne faites que lire les données.","Pour afficher les produits d'une boutique B sur la page d'accueil d'une boutique A en multiboutique PrestaShop, la solution recommandée est un module personnalisé avec requête SQL ciblant explicitement l'id_shop source, combiné à une génération d'URLs via Shop::setContext() pour pointer vers le bon domaine.",8,"2026-03-21T15:09:14.000Z",[],"Utilisation de PrestaShop : configuration et difficultés",{"columns":67},[68,84,114,135],{"title":69,"links":70},"Plateforme",[71,75,78,81],{"label":72,"href":73,"external":74},"Offre Starter (2 500 €)","\u002Foffre-starter",false,{"label":76,"href":77,"external":74},"Devenir Ambassadeur","\u002Fambassadeur",{"label":79,"href":80,"external":74},"Modules PrestaShop","\u002Fmodules",{"label":82,"href":83,"external":20},"CodeMyShop.com","https:\u002F\u002Fcodemyshop.com",{"title":85,"links":86},"Le Synedre",[87,90,93,96,99,102,105,108,111],{"label":88,"href":89,"external":74},"L'histoire","\u002Fsynedre",{"label":91,"href":92,"external":74},"Constitution","\u002Fsynedre\u002Fconstitution",{"label":94,"href":95,"external":74},"L'équipe","\u002Fequipe",{"label":97,"href":98,"external":74},"Le réacteur en direct","\u002Freacteur",{"label":100,"href":101,"external":74},"Le Drill (entraînement)","\u002Fdrill",{"label":103,"href":104,"external":74},"Protocole de réunion","\u002Fsynedre\u002Freunion",{"label":106,"href":107,"external":74},"Les agents IA","\u002Fagents-ia",{"label":109,"href":110,"external":74},"La Conduite","\u002Fsynedre\u002Fconduite",{"label":112,"href":113,"external":74},"Charte plateforme","\u002Fsynedre\u002Fcharte",{"title":115,"links":116},"Ressources",[117,120,123,126,129,132],{"label":118,"href":119,"external":74},"Blog","\u002Fblog",{"label":121,"href":122,"external":74},"Academy","\u002Facademy",{"label":124,"href":125,"external":74},"Dictionnaire","\u002Fdictionnaire",{"label":127,"href":128,"external":74},"Expertise PrestaShop","\u002Fexpertise",{"label":130,"href":131,"external":74},"Flywheel","\u002Fflywheel",{"label":133,"href":134,"external":74},"Manifeste","\u002Fmanifeste",{"title":136,"links":137},"À propos",[138,141,144],{"label":139,"href":140,"external":74},"Alexandre Carette","\u002Fa-propos",{"label":142,"href":143,"external":74},"Dossier de presse","\u002Fpresse",{"label":145,"href":146,"external":74},"Contact","\u002Fcontact",{"items":148},[149,158,164,170,178,186,192,198],{"id":150,"type":151,"label":152,"href":128,"icon":154,"description":154,"badge":154,"groupTitle":154,"style":154,"gridColumns":154,"cssClass":154,"psCategoryId":154,"showPsChildren":74,"position":155,"children":156,"psChildren":157},41,"link",{"fr":153},"Expertise",null,0,[],[],{"id":159,"type":151,"label":160,"href":119,"icon":154,"description":154,"badge":154,"groupTitle":154,"style":154,"gridColumns":154,"cssClass":154,"psCategoryId":154,"showPsChildren":74,"position":161,"children":162,"psChildren":163},42,{"fr":118},1,[],[],{"id":165,"type":151,"label":166,"href":80,"icon":154,"description":154,"badge":154,"groupTitle":154,"style":154,"gridColumns":154,"cssClass":154,"psCategoryId":154,"showPsChildren":74,"position":167,"children":168,"psChildren":169},43,{"fr":79},2,[],[],{"id":171,"type":151,"label":172,"href":174,"icon":154,"description":154,"badge":154,"groupTitle":154,"style":154,"gridColumns":154,"cssClass":154,"psCategoryId":154,"showPsChildren":74,"position":175,"children":176,"psChildren":177},44,{"fr":173},"Outils IA","\u002Foutils-ia",3,[],[],{"id":179,"type":151,"label":180,"href":73,"icon":154,"description":154,"badge":154,"groupTitle":154,"style":182,"gridColumns":154,"cssClass":154,"psCategoryId":154,"showPsChildren":74,"position":183,"children":184,"psChildren":185},45,{"fr":181},"Offre Starter ✨",{"highlight":20},4,[],[],{"id":187,"type":151,"label":188,"href":122,"icon":154,"description":154,"badge":154,"groupTitle":154,"style":154,"gridColumns":154,"cssClass":154,"psCategoryId":154,"showPsChildren":74,"position":189,"children":190,"psChildren":191},46,{"fr":121},5,[],[],{"id":193,"type":151,"label":194,"href":140,"icon":154,"description":154,"badge":154,"groupTitle":154,"style":154,"gridColumns":154,"cssClass":154,"psCategoryId":154,"showPsChildren":74,"position":195,"children":196,"psChildren":197},47,{"fr":136},6,[],[],{"id":199,"type":151,"label":200,"href":146,"icon":154,"description":154,"badge":154,"groupTitle":154,"style":154,"gridColumns":154,"cssClass":154,"psCategoryId":154,"showPsChildren":74,"position":201,"children":202,"psChildren":203},48,{"fr":145},7,[],[],{"header":205},{"logo":206,"topBar":211,"contactEmail":214,"features":215,"navBar":154},{"src":207,"alt":208,"text":139,"href":209,"class":210},"\u002Flogo-ac.svg","Alexandre Carette — Architecte E-commerce Souverain","\u002F","h-10 w-10",{"message":154,"showLanguages":74,"align":212,"languages":213},"left",[],"contact@alexandrecarette.fr",{"showSearch":74,"showWishlist":74,"showLogin":20,"showContact":74,"showCart":74,"stickyHeader":20,"headerLayout":216},"inline",{"footer":218},{"theme":219,"description":154,"hours":154,"logo":220,"contact":221,"social":222,"bottomBar":232},"dark",{"src":207,"href":209,"alt":139},{"email":154,"phone":154,"address":154,"cta":154},[223,226,229],{"platform":224,"href":225,"label":224},"linkedin","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Falexandre-carette\u002F",{"platform":227,"href":228,"label":227},"malt","https:\u002F\u002Fwww.malt.fr\u002Fprofile\u002Falexandrecarette",{"platform":230,"href":231,"label":230},"github","https:\u002F\u002Fgithub.com\u002Fprest4cafe",{"copyright":154},{"academy":234,"blog":235,"expertise":246},[],[236,240,243],{"title":237,"url":238,"score":161,"type":239},"PrestaShop headless avec Nuxt 3 : pourquoi séparer back et front","\u002Fblog\u002Fprestashop\u002Farchitecture\u002Fprestashop-headless-nuxt-separation-front-back","blog",{"title":241,"url":242,"score":161,"type":239},"PrestaShop headless : Nuxt 3, pas Next.js — le choix souverain","\u002Fblog\u002Fprestashop\u002Farchitecture\u002Fprestashop-headless-nuxt-nextjs-souverainete",{"title":244,"url":245,"score":161,"type":239},"Sylius rachète PrestaShop : ce que ça change pour vous","\u002Fblog\u002Fprestashop\u002Farchitecture\u002Fsylius-rachat-prestashop-headless-souverainete",[]]