En este tutorial, vamos a agregar recomendaciones de productos complementarios al agregar uno al carrito de compras rápidas.
Antes de avanzar vamos a necesitar tener el carrito de compras rápidas siguiendo este tutorial.
HTML
1. Vamos a crear un nuevo snipplet con el nombre cart-related-products.tpl dentro de la carpeta snipplets. El código para este es el siguiente:
{# Set related products classes #} {% set title_class = 'h4 text-center mt-3' %} {% set products_container_class = 'position-relative swiper-container-horizontal' %} {% set slider_container_class = 'swiper-container' %} {% set swiper_wrapper_class = 'swiper-wrapper' %} {% set slider_control_pagination_class = 'swiper-pagination' %} {% set slider_control_class = 'icon-inline icon-w-8 icon-2x svg-icon-text' %} {% set slider_control_prev_class = 'swiper-button-prev' %} {% set slider_control_next_class = 'swiper-button-next' %} {% set control_prev = include ('snipplets/svg/chevron-left.tpl', {svg_custom_class: slider_control_class}) %} {% set control_next = include ('snipplets/svg/chevron-right.tpl', {svg_custom_class: slider_control_class}) %} {# Related cart products #} {% set related_section_id = 'related-products-notification' %} {% set related_products = related_products_list | length > 0 %} {% if related_products %} {{ component( 'products-section',{ title: 'Sumá a tu compra' | translate, id: related_section_id, data_component: related_section_id, products_amount: related_products_list | length, products_array: related_products_list, product_template_path: 'snipplets/grid/item.tpl', product_template_params: {'slide_item': true, 'reduced_item': true}, slider_controls_position: 'bottom', slider_pagination: true, svg_sprites: false, section_classes: { section: 'js-related-products-notification', title: title_class, products_container: products_container_class, slider_container: 'js-swiper-related-products-notification ' ~ slider_container_class, slider_wrapper: swiper_wrapper_class, slider_control: 'd-none d-md-block', slider_control_pagination: 'js-swiper-related-products-notification-pagination ' ~ slider_control_pagination_class, slider_control_prev_container: 'js-swiper-related-products-notification-prev ' ~ slider_control_prev_class, slider_control_next_container: 'js-swiper-related-products-notification-next ' ~ slider_control_next_class, }, custom_control_prev: control_prev, custom_control_next: control_next, }) }} {% endif %}
Podemos observar que estamos incluyendo el snipplet item.tpl de la carpeta snipplets/grid (basado en el theme Base), puede que en tu caso necesites incluir el snipplet single_product.tpl. Lo importante es usar el mismo snipplet que usamos para el item en los listados de productos, como los que están en los templates category.tpl o search.tpl.
Por otro lado es importante mencionar que estamos usando el componente privado de "products-section". Para más información las opciones de este componente te recomendamos este artículo.
2. Dentro de item.tpl vamos a agregar en el div donde tenemos las clases para las columnas de Bootstrap el condicional {% if slide_item %}js-item-slide swiper-slide{% endif %}. Debajo está un ejemplo de como aplicarlo:
<div class="{% if slide_item %}js-item-slide swiper-slide{% else %}col-12 col-sm-4{% endif %} item item-product"> ... </div>
3. Luego vamos a agregar la condición "reduced_item" en varios lugares para agregar clases de CSS y evitar mostrar contenido que no es necesario para el contexto reducido en el que se mostrarán las recomendaciones.
Primero vamos a sumar la clase "item-product-reduced" de la siguiente manera
<div class="{% if slide_item %}js-item-slide swiper-slide{% else %}col-12 col-sm-4{% endif %} item item-product {% if reduced_item %}item-product-reduced{% endif %}"> ... </div>
Luego vamos a usar la condición {% if not reduced_item %} para evitar mostrar las etiquetas promocionales, el botón de compra rápida, el precio promocional, el precio con descuento por medio de pago y las cuotas. Debajo un ejemplo de como funcionaría con las cuotas:
{% if not reduced_item %} {{ component('installments', {'location' : 'product_item', container_classes: { installment: "item-installments"}}) }} {% endif %}
De esta forma el item de producto recomendado quedará reducido sólo a la imagen, el nombre y el precio.
4. Dentro del archivo donde se incluye el carrito de compras rápidas, Incluimos el modal que va a contener las recomendaciones. En este caso será incluido en el tpl header.tpl, de la siguiente forma:
{% if not store.is_catalog and settings.ajax_cart and template != 'cart' %} ... Modal del carrito de compras rápidas ... {% if settings.add_to_cart_recommendations %} {# Recommended products on add to cart #} {% embed "snipplets/modal.tpl" with{modal_id: 'related-products-notification', modal_class: 'bottom modal-overflow-none modal-bottom-sheet h-auto', modal_header_class: 'px-0 pt-0 mb-2 m-0 w-100', modal_position: 'bottom', modal_transition: 'slide', modal_width: 'centered modal-centered-md-600px p-3'} %} {% block modal_head %} {% block page_header_text %}{{ '¡Agregado al carrito!' | translate }}{% endblock page_header_text %} {% endblock %} {% block modal_body %} {# Product added info #} {% include "snipplets/notification-cart.tpl" with {related_products: true} %} {# Product added recommendations #} <div class="js-related-products-notification-container" style="display: none"></div> {% endblock %} {% endembed %} {% endif %} {% endif %}
5. En el archivo notification.tpl, donde se encuentran las notificaciones en general, buscamos la notificación de agregado al carrito que se encuentra bajo el condicional {% if add_to_cart %} y la reemplazamos por lo siguiente:
{# Add to cart notification #} {% if add_to_cart %} {% include "snipplets/notification-cart.tpl" %} {% endif %}
6. Creamos un nuevo archivo notification-cart.tpl dentro de la carpeta snipplets con el siguiente contenido:
{% set notification_without_recommendations_classes = 'js-alert-added-to-cart notification-floating notification-hidden' %} {% set notification_wrapper_classes = related_products ? 'row' : not related_products and add_to_cart_fixed ? notification_without_recommendations_classes ~ ' notification-fixed-bottom-right mb-md-2 mr-md-2' : notification_without_recommendations_classes %} <div class="{{ notification_wrapper_classes }}" {% if not related_products %}style="display: none;"{% endif %}> <div class="{% if related_products %}col-md-6{% else %}notification notification-primary position-relative {% if not add_to_cart_mobile %}col-12 float-right{% endif %}{% endif %}"> {% if not related_products %} <div class="h6 text-center mb-3 mr-3"> <strong>{{ '¡Ya agregamos tu producto al carrito!' | translate }}</strong> </div> <div class="js-cart-notification-close notification-close"> {% include "snipplets/svg/times.tpl" with {svg_custom_class: "icon-inline svg-icon-primary"} %} </div> {% endif %} <div class="js-cart-notification-item row{% if related_products %} align-items-center{% endif %}" data-store="cart-notification-item"> <div class="{% if related_products %}col-md-3 col-2{% else %}col-3{% endif %} pr-0 notification-img"> <img src="" class="js-cart-notification-item-img img-fluid" /> </div> <div class="{% if related_products %}col-md-9 col-10{% else %}col-9{% endif %} text-left"> <div class="mb-1"> <span class="js-cart-notification-item-name"></span> <span class="js-cart-notification-item-variant-container" style="display: none;"> (<span class="js-cart-notification-item-variant"></span>) </span> </div> <div class="mb-1"> <span class="js-cart-notification-item-quantity"></span> <span> x </span> <span class="js-cart-notification-item-price"></span> </div> </div> </div> {% if related_products %} </div> <div class="col-md-6"> {% endif %} <div class="row text-primary h5 font-weight-normal mt-2 mb-3{% if related_products %} mt-md-0{% endif %}"> <span class="col-auto text-left"> <strong>{{ "Total" | translate }}</strong> (<span class="js-cart-widget-amount"> {{ "{1}" | translate(cart.items_count ) }} </span> <span class="js-cart-counts-plural" style="display: none;"> {{ 'productos' | translate }}): </span> <span class="js-cart-counts-singular" style="display: none;"> {{ 'producto' | translate }}): </span> </span> <strong class="js-cart-total col text-right">{{ cart.total | money }}</strong> </div> <a href="#" class="{% if related_products %}js-modal-close{% else %}js-cart-notification-close{% endif %} js-modal-open js-fullscreen-modal-open btn btn-primary btn-medium w-100 d-inline-block" data-toggle="#modal-cart" data-modal-url="modal-fullscreen-cart"> {{ 'Ver carrito' | translate }} </a> </div> </div>
7. En caso de no tener el componente de modal, vamos a necesitar agregar el archivo modal.tpl dentro de la carpeta snipplets
{# /*============================================================================ #Modal ==============================================================================*/ #Properties // ID // Position - Top, Right, Bottom, Left // Transition - Slide and Fade // Width - Full and Box // modal_form_action - For modals that has a form // modal_fixed_footer - For modals with fixed footer. Need to include the fixed part inside the footer #Head // Block - modal_head #Body // Block - modal_body #Footer // Block - modal_footer #} {% set modal_overlay = modal_overlay | default(true) %} <div id="{{ modal_id }}" class="js-modal {% if modal_mobile_full_screen %}js-fullscreen-modal{% endif %} modal modal-{{ modal_class }} modal-{{modal_position}} transition-{{modal_transition}} modal-{{modal_width}} transition-soft {% if modal_zindex_top %}modal-zindex-top{% endif %}" style="display: none;" {% if data_component %}data-component="{{ data_component }}"{% endif %}> {% if modal_form_action %} <form action="{{ modal_form_action }}" method="post" class="{{ modal_form_class }} {% if modal_footer and modal_fixed_footer %}modal-with-fixed-footer{% endif %}" {% if modal_form_hook %}data-store="{{ modal_form_hook }}"{% endif %}> {% endif %} {% if modal_footer and modal_fixed_footer %} <div class="modal-with-fixed-footer"> <div class="modal-scrollable-area"> {% endif %} <div class="js-modal-close {% if modal_mobile_full_screen %}js-fullscreen-modal-close{% endif %} modal-header"> <span class="modal-close"> {% include "snipplets/svg/times.tpl" with {svg_custom_class: "icon-inline svg-icon-text"} %} </span> {% block modal_head %}{% endblock %} </div> <div class="modal-body"> {% block modal_body %}{% endblock %} </div> {% if modal_footer and modal_fixed_footer %} </div> {% endif %} {% if modal_footer %} <div class="modal-footer {% if not modal_fixed_footer %}d-md-block{% endif %} {{ modal_footer_class }}"> {% block modal_foot %}{% endblock %} </div> {% if modal_fixed_footer %} </div> {% endif %} {% endif %} {% if modal_form_action %} </form> {% endif %} </div> <div class="js-modal-overlay {% if modal_mobile_full_screen %}js-fullscreen-overlay{% endif %} modal-overlay {% if modal_zindex_top %}modal-zindex-top{% endif %}" data-modal-id="#{{ modal_id }}" style="display: none;"></div>
8. Por último para la parte de HTML, necesitamos agregar una carpeta SVG dentro de la carpeta snipplets. Acá vamos sumar los SVGs que usamos para los iconos en el carrito.
chevron-left.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path d="M231.293 473.899l19.799-19.799c4.686-4.686 4.686-12.284 0-16.971L70.393 256 251.092 74.87c4.686-4.686 4.686-12.284 0-16.971L231.293 38.1c-4.686-4.686-12.284-4.686-16.971 0L4.908 247.515c-4.686 4.686-4.686 12.284 0 16.971L214.322 473.9c4.687 4.686 12.285 4.686 16.971-.001z"/></svg>
chevron-right.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path d="M24.707 38.101L4.908 57.899c-4.686 4.686-4.686 12.284 0 16.971L185.607 256 4.908 437.13c-4.686 4.686-4.686 12.284 0 16.971L24.707 473.9c4.686 4.686 12.284 4.686 16.971 0l209.414-209.414c4.686-4.686 4.686-12.284 0-16.971L41.678 38.101c-4.687-4.687-12.285-4.687-16.971 0z"/></svg>
times.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"/></svg>
CSS
Requisito:
Tener agregados en tu diseño las clases helpers. Podés seguir este este pequeño tutorial para hacerlo (simplemente es copiar y pegar algunas clases, no toma más de 1 minuto).
Como en este ejemplo usamos un slider con Swiper, necesitamos agregar el plugin. Para ver cómo hacerlo podés leer este corto artículo y luego continuar con este tutorial.
Si ya tenes el componente de modal en tu tienda, es probable que no necesites gran parte del CSS debajo:
1. Agregamos el siguiente SASS de colores en static/style-colors.scss.tpl (o la hoja de tu diseño que tenga los colores y tipografías de la tienda). Recordá que las variables de colores y tipografías pueden variar respecto a tu diseño:
{# /* // Modals */ #} .modal{ color: $main-foreground; background-color:$main-background; }
2. Agregar los estilos dentro del archivo static/style-critical.tpl
Si en tu diseño usas una hoja de estilos para el CSS crítico, vamos a necesitar agregar el código debajo dentro de la misma, pero si no es el caso podés unificar el CSS de los pasos 2 y 3 en un solo archivo.
.item-product-reduced .item-image { height: 145px; } .item-product-reduced .item-image img { width: 100%; height: 145px; object-fit: cover; } {# /* // Min width 768px */ #} @media (min-width: 768px) { .item-product-reduced .item-image, .item-product-reduced .item-image img { height: 180px; } }
3. Agregar los estilos dentro del archivo static/style-async.tpl
Si en tu diseño usas una hoja de estilos para CSS asíncrono, vamos a necesitar agregar el código debajo dentro de la misma, pero si no es el caso podés unificar el CSS de los pasos 2 y 3 en un solo archivo.
{# /* // Modals */ #} .modal { position: fixed; top: 0; display: block; width: 80%; height: 100%; padding: 10px; -webkit-overflow-scrolling: touch; overflow-y: auto; transition: all .2s cubic-bezier(.16,.68,.43,.99); z-index: 20000; &-img-full{ max-width: 100%; max-height: 190px; } &-header{ width: calc(100% + 20px); margin: -10px 0 10px -20px; padding: 10px 15px 10px 25px; font-size: 20px; } &-footer{ padding: 10px 0; clear: both; } &-with-fixed-footer { display: flex; flex-direction: column; height: 100%; .modal-scrollable-area { height: 100%; overflow: auto; } } &-full { width: 100%; } &-docked-md{ width: 100%; } &-docked-small{ width: 80%; } &-top{ top: -100%; left: 0; } &-bottom{ top: 100%; left: 0; } &-left{ left: -100%; } &-right{ right: -100%; } &-centered{ height: 100%; width: 100%; &-small{ left: 50%; width: 80%; height: auto; @include prefix(transform, translate(-50%, -50%), webkit ms moz o); .modal-body{ min-height: 150px; max-height: 400px; overflow: auto; } } } &-top.modal-show, &-bottom.modal-show { top: 0; &.modal-centered-small{ top: 50%; } } &-bottom-sheet { top: initial; bottom: -100%; height: auto; &.modal-show { top: initial; bottom: 0; height: auto; } } &-left.modal-show { left: 0; } &-right.modal-show { right: 0; } &-close { display: inline-block; padding: 1px 5px 5px 0; margin-right: 5px; vertical-align: middle; cursor: pointer; } .tab-group{ margin: 0 -10px 20px -10px; } } .modal-overlay{ position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: #00000047; z-index: 10000; &.modal-zindex-top{ z-index: 20000; } } @media (min-width: 768px) { {# /* Modals */ #} .modal{ &-centered{ height: 80%; width: 80%; left: 10%; margin: 5% auto; &-small{ left: 50%; width: 30%; height: auto; max-height: 80%; margin: 0; } &-md-600px { left: 50%; width: 600px; transform: translateX(-50%); } } &-docked-md{ width: 500px; overflow-x: hidden; &-centered{ left: calc(50% - 250px); bottom: auto; height: auto; } } &-bottom-sheet { top: 100%; &.modal-show { top: 0; bottom: auto; } } &-docked-small{ width: 350px; } } }
JS
1. Si no tenes el componente de modal, vamos a necesitar sumar el JS relacionado a este componente dentro del archivo store.js.tpl (o donde tengas tus funciones de JS) con el siguiente código:
{#/*============================================================================ #Modals ==============================================================================*/ #} {# Full screen mobile modals back events #} if (window.innerWidth < 768) { {# Clean url hash function #} cleanURLHash = function(){ const uri = window.location.toString(); const clean_uri = uri.substring(0, uri.indexOf("#")); window.history.replaceState({}, document.title, clean_uri); }; {# Go back 1 step on browser history #} goBackBrowser = function(){ cleanURLHash(); history.back(); }; {# Clean url hash on page load: All modals should be closed on load #} if(window.location.href.indexOf("modal-fullscreen") > -1) { cleanURLHash(); } {# Open full screen modal and url hash #} jQueryNuvem(document).on("click", ".js-fullscreen-modal-open", function(e) { e.preventDefault(); var modal_url_hash = jQueryNuvem(this).data("modalUrl"); window.location.hash = modal_url_hash; }); {# Close full screen modal: Remove url hash #} jQueryNuvem(document).on("click", ".js-fullscreen-modal-close", function(e) { e.preventDefault(); goBackBrowser(); }); {# Hide panels or modals on browser backbutton #} window.onhashchange = function() { if(window.location.href.indexOf("modal-fullscreen") <= -1) { {# Close opened modal #} if(jQueryNuvem(".js-fullscreen-modal").hasClass("modal-show")){ {# Remove body lock only if a single modal is visible on screen #} if(jQueryNuvem(".js-modal.modal-show").length == 1){ jQueryNuvem("body").removeClass("overflow-none"); } var $opened_modal = jQueryNuvem(".js-fullscreen-modal.modal-show"); var $opened_modal_overlay = $opened_modal.prev(); $opened_modal.removeClass("modal-show"); setTimeout(() => $opened_modal.hide(), 500); $opened_modal_overlay.fadeOut(500); } } } } modalOpen = function(modal_id){ var $overlay_id = jQueryNuvem('.js-modal-overlay[data-modal-id="' + modal_id + '"]'); if (jQueryNuvem(modal_id).hasClass("modal-show")) { let modal = jQueryNuvem(modal_id).removeClass("modal-show"); setTimeout(() => modal.hide(), 500); } else { {# Lock body scroll if there is no modal visible on screen #} if(!jQueryNuvem(".js-modal.modal-show").length){ jQueryNuvem("body").addClass("overflow-none"); } $overlay_id.fadeIn(400); jQueryNuvem(modal_id).detach().appendTo("body"); $overlay_id.detach().insertBefore(modal_id); jQueryNuvem(modal_id).show().addClass("modal-show"); } }; jQueryNuvem(document).on("click", ".js-modal-open", function(e) { e.preventDefault(); var modal_id = jQueryNuvem(this).data('toggle'); modalOpen(modal_id); }); jQueryNuvem(document).on("click", ".js-modal-close", function(e) { e.preventDefault(); {# Remove body lock only if a single modal is visible on screen #} if(jQueryNuvem(".js-modal.modal-show").length == 1){ jQueryNuvem("body").removeClass("overflow-none"); } var $modal = jQueryNuvem(this).closest(".js-modal"); var modal_id = $modal.attr('id'); var $overlay_id = jQueryNuvem('.js-modal-overlay[data-modal-id="#' + modal_id + '"]'); $modal.removeClass("modal-show"); setTimeout(() => $modal.hide(), 500); $overlay_id.fadeOut(500); {# Close full screen modal: Remove url hash #} if ((window.innerWidth < 768) && (jQueryNuvem(this).hasClass(".js-fullscreen-modal-close"))) { goBackBrowser(); } }); jQueryNuvem(document).on("click", ".js-modal-overlay", function(e) { e.preventDefault(); {# Remove body lock only if a single modal is visible on screen #} if(jQueryNuvem(".js-modal.modal-show").length == 1){ jQueryNuvem("body").removeClass("overflow-none"); } var modal_id = jQueryNuvem(this).data('modalId'); let modal = jQueryNuvem(modal_id).removeClass("modal-show"); setTimeout(() => modal.hide(), 500); jQueryNuvem(this).fadeOut(500); if (jQueryNuvem(this).hasClass("js-fullscreen-overlay") && (window.innerWidth < 768)) { cleanURLHash(); } });
2. En el mismo archivo store.js.tpl necesitamos ubicar la función en la cuál se agrega el producto al carrito de compras rápidas. Vamos a buscar la variable "callback_add_to_cart" y sumarle el parámetro "html_notification_related_products" a la función de la siguiente manera:
var callback_add_to_cart = function(html_notification_related_products){
Luego necesitamos ubicar la parte en la cuál se abre el carrito o se muestra la notificación luego de que un producto es agregado al carrito y antes sumar el siguiente código
let notificationWithRelatedProducts = false; {% if settings.add_to_cart_recommendations %} {# Show added to cart product related products #} function recommendProductsOnAddToCart(){ jQueryNuvem('.js-related-products-notification-container').html(""); modalOpen('#related-products-notification'); jQueryNuvem('.js-related-products-notification-container').html(html_notification_related_products).show(); {# Recommendations swiper #} // Set loop for recommended products function calculateRelatedNotificationLoopVal(sectionSelector) { let productsAmount = jQueryNuvem(sectionSelector).attr("data-related-amount"); let loopVal = false; const applyLoop = (window.innerWidth < 768 && productsAmount > 2) || (window.innerWidth > 768 && productsAmount > 3); if (applyLoop) { loopVal = true; } return loopVal; } let cartRelatedLoopVal = calculateRelatedNotificationLoopVal(".js-related-products-notification"); // Create new swiper on add to cart createSwiper('.js-swiper-related-products-notification', { lazy: true, loop: cartRelatedLoopVal, watchOverflow: true, threshold: 5, watchSlideProgress: true, watchSlidesVisibility: true, spaceBetween: 15, slideVisibleClass: 'js-swiper-slide-visible', slidesPerView: 2, pagination: { el: '.js-swiper-related-products-notification-pagination', clickable: true, }, navigation: { nextEl: '.js-swiper-related-products-notification-next', prevEl: '.js-swiper-related-products-notification-prev', }, breakpoints: { 768: { slidesPerView: 3, } } }); } notificationWithRelatedProducts = html_notification_related_products != null; if(notificationWithRelatedProducts){ if (isQuickShop) { setTimeout(function(){ recommendProductsOnAddToCart(); },300); }else{ recommendProductsOnAddToCart(); } } {% endif %}
Por último vamos a englobar a la parte donde se abre el carrito o se muestra la notificación de agregado al carrito con el siguiente condicional:
if(!notificationWithRelatedProducts){ ... código para mostrar el carrito o la notificación ... }
Configuraciones
En el archivo config/settings.txt vamos a agregar la opción para prender o apagar las recomendaciones dentro de la sección “Carrito de compras”.
title title = Recomendaciones de productos checkbox name = add_to_cart_recommendations description = Sugerir productos complementarios al agregar uno al carrito de compras rápidas subtitle subtitle = <a target='_blank' href='https://ayuda.tiendanube.com/es_AR/123159-detalle-del-producto/como-seleccionar-los-productos-relacionados-en-tiendanube' class='js-checkbox-help-link'>Más sobre productos relacionados</a>
Traducciones
En este paso agregamos los textos para las traducciones en el archivo config/translations.txt
es "¡Agregado al carrito!" pt "Adicionado ao carrinho!" en "Added to cart!" es_mx "¡Agregado al carrito!" es "Ver carrito" pt "Ver carrinho" en "View cart" es_mx "Ver carrito" es "Total" pt "Total" en "Total" es_mx "Total" es "productos" pt "produtos" en "products" es_mx "productos" es "producto" pt "produto" en "product" es_mx "producto" es "Sumá a tu compra" pt "Compre também" en "Buy also" es_mx "Suma a tu compra" es "Recomendaciones de productos" pt "Recomendações de produtos" es_mx "Recomendaciones de productos" es "Sugerir productos complementarios al agregar uno al carrito de compras rápidas" pt "Sugerir produtos complementares ao adicionar um ao carrinho de compra rápida" es_mx "Sugerir productos complementarios al agregar uno al carrito de compras rápidas" es "<a target='_blank' href='https://ayuda.tiendanube.com/es_AR/123159-detalle-del-producto/como-seleccionar-los-productos-relacionados-en-tiendanube' class='js-checkbox-help-link'>Más sobre productos relacionados</a>" pt "<a target='_blank' href='https://atendimento.nuvemshop.com.br/pt_BR/pagina-do-produto/como-selecionar-os-produtos-relacionados-na-nuvemshop' class='js-checkbox-help-link'>Mais sobre produtos relacionados</a>" es_mx "<a target='_blank' href='https://ayuda.tiendanube.com/es_MX/123159-detalle-del-producto/como-seleccionar-los-productos-relacionados-en-tiendanube' class='js-checkbox-help-link'>Más sobre productos relacionados</a>"
Activación
Listo, una vez que se relacionen productos complementarios desde el formulario de producto en el administrador y lo actives la funcionalidad desde la sección Carrito de compras en la personalización de la tienda, se verán las recomendaciones de productos complementarios al agregar uno al carrito.
Si no existen complementarios relacionados, el flujo de compra continuará normalmente. ¡Excelente!