0

The only solution i found so far is to add cacheable="false" to recently_viewed block in xml, but this did not work. Is there any other way to force magento show "Recently Viewed" block on product page when Full Page Cache is enable?

2 Answers 2

1

This is a known issue with Magento 2, the issue can be tracked on GitHub here.

I believe the block will need 'hole punching' through the cache, there are some answers on how to disable the cache per block here and here There is also some related info on the dev docs here.

Be careful using cacheable="false" as it will prevent the whole page from being cached (this may be changed in a future update, if so please update this answer and remove this paragraph).

1

I finally made it work. So the reason the block not show up is because session in magento act a bit odd when Full Page Cache is enable. And that's why in sql query that gets recently viewed products we have empty visitor_id or customer_id and as a result - 0 records found. To solve this I used \Magento\Framework\App\Http\Context object and saved visitor_id or customer_id in there.

Here is the complete solution:

in Vendor/Module/di.xml

<preference for="Magento\Reports\Model\ResourceModel\Product\Index\Viewed\Collection" 
    type="Vendor\Module\Model\ResourceModel\Product\Index\Viewed\Collection"/>

In Vendor\Module\Model\ResourceModel\Product\Index\Viewed\Collection

namespace Vendor\Module\Model\ResourceModel\Product\Index\Viewed;

class Collection extends \Magento\Reports\Model\ResourceModel\Product\Index\Viewed\Collection
{

    protected $httpContext;

    public function __construct(
        \Magento\Framework\Data\Collection\EntityFactory $entityFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magento\Eav\Model\Config $eavConfig,
        \Magento\Framework\App\ResourceConnection $resource,
        \Magento\Eav\Model\EntityFactory $eavEntityFactory,
        \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper,
        \Magento\Framework\Validator\UniversalFactory $universalFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Module\Manager $moduleManager,
        \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory,
        \Magento\Catalog\Model\ResourceModel\Url $catalogUrl,
        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
        \Magento\Customer\Model\Session $customerSession,
        \Magento\Framework\Stdlib\DateTime $dateTime,
        \Magento\Customer\Api\GroupManagementInterface $groupManagement,
        \Magento\Customer\Model\Visitor $customerVisitor,
        \Magento\Framework\App\Http\Context  $httpContext,
        \Magento\Framework\DB\Adapter\AdapterInterface $connection = null
    ) {

        parent::__construct(
            $entityFactory,
            $logger,
            $fetchStrategy,
            $eventManager,
            $eavConfig,
            $resource,
            $eavEntityFactory,
            $resourceHelper,
            $universalFactory,
            $storeManager,
            $moduleManager,
            $catalogProductFlatState,
            $scopeConfig,
            $productOptionFactory,
            $catalogUrl,
            $localeDate,
            $customerSession,
            $dateTime,
            $groupManagement,
            $customerVisitor,
            $connection
        );

        $this->httpContext= $httpContext;
    }

    protected function _getWhereCondition()
    {
      $condition = [];
      $myCustomerId = $this->httpContext->getValue('my_customer_id');
      $myVisitorId = $this->httpContext->getValue('my_visitor_id');

      if($myCustomerId){
          $condition['customer_id'] = $myCustomerId;
      }elseif ($this->_customerSession->isLoggedIn()) {
          $condition['customer_id'] =    $this->_customerSession->getCustomerId();
          $this->httpContext->setValue('my_customer_id',$condition['customer_id'],false);
      }elseif ($this->_customerId) {
        $condition['customer_id'] = $this->_customerId;
        $this->httpContext->setValue('my_customer_id',$condition['customer_id'],false);
      }elseif($myVisitorId) {
         $condition['visitor_id'] = $myVisitorId;
      }else{
         $condition['visitor_id'] = $this->_customerVisitor->getId();
         if($condition['visitor_id'])
           $this->httpContext->setValue('my_visitor_id',$condition['visitor_id'],false);
        }

      return $condition;
   }
}
2
  • I tried it on Magento 2.2.6 and it's doesn't work Commented Dec 3, 2018 at 16:04
  • Not working for me Magento 2.4.6p3 Commented Dec 29, 2023 at 10:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.