How to change a redirect after the add to cart action?¶

Currently Sylius by default is using route definition and sylius-add-to-cart.js script to handle redirect after successful add to cart action.

sylius_shop_partial_cart_add_item:
    path: /add-item
    methods: [GET]
    defaults:
        _controller: sylius.controller.order_item:addAction
        _sylius:
            template: $template
            factory:
                method: createForProduct
                arguments: [expr:service('sylius.repository.product').find($productId)]
            form:
                type: Sylius\Bundle\CoreBundle\Form\Type\Order\AddToCartType
                options:
                    product: expr:service('sylius.repository.product').find($productId)
            redirect:
                route: sylius_shop_cart_summary
                parameters: {}
$.fn.extend({
    addToCart: function () {
        var element = $(this);
        var href = $(element).attr('action');
        var redirectUrl = $(element).data('redirect');
        var validationElement = $('#sylius-cart-validation-error');

        $(element).api({
            method: 'POST',
            on: 'submit',
            cache: false,
            url: href,
            beforeSend: function (settings) {
                settings.data = $(this).serialize();

                return settings;
            },
            onSuccess: function (response) {
                validationElement.addClass('hidden');
                window.location.replace(redirectUrl);
            },
            onFailure: function (response) {
                validationElement.removeClass('hidden');
                var validationMessage = '';

                $.each(response.errors.errors, function (key, message) {
                    validationMessage += message;
                });
                validationElement.html(validationMessage);
                $(element).removeClass('loading');
            },
        });
    }
});

If you want to have custom logic after cart add action you can use ResourceControllerEvent to set your custom response.

Let’s assume that you would like such a feature in your system:

<?php

final class ChangeRedirectAfterAddingToCartListener
{
    /**
     * @var RouterInterface
     */
    private $router;

    /**
     * @param RouterInterface $router
     */
    public function __construct(RouterInterface $router)
    {
        $this->router = $router;
    }

    /**
     * @param ResourceControllerEvent $event
     */
    public function onSuccessfulAddToCart(ResourceControllerEvent $event)
    {
        if (!$event->getSubject() instanceof OrderItemInterface) {
            throw new \LogicException(
                sprintf('This listener operates only on order item, got "%s"', get_class($event->getSubject()))
            );
        }

        $newUrl = $this->router->generate('your_new_route_name', []);

        $event->setResponse(new RedirectResponse($newUrl));
    }
}
<service id="sylius.listener.change_redirect_after_adding_to_cart" class="Sylius\Bundle\ShopBundle\EventListener\ChangeRedirectAfterAddingToCartListener">
    <argument type="service" id="router" />
    <tag name="kernel.event_listener" event="sylius.order_item.post_add" method="onSuccessfulAddToCart" />
</service>

Next thing to do is handling it by your frontend application.