This issue is still reproducible on Magento 2.0.0 Stable.
There is a feature in Magento 2 exception handling, which prevents rendering of broken blocks while all other blocks are still rendered. In developer mode it is disabled and all exceptions are displayed right in browser. In default and production modes, if exception occurs during block rendering, the block will just be removed from the output (corresponding exception is still logged to var/log/system.log). See \Magento\Framework\View\Layout::renderNonCachedElement()
.
Following exception occurs during checkout block rendering on product page and that is why this block is missing: main.CRITICAL: No such entity with customerId = [] []
.
The reason for this exception is that customer data in session storage is in inconsistent state (customerLoggedIn == true
and customer data is missing) after \Magento\PageCache\Model\Layout\DepersonalizePlugin::afterGenerateXml()
execution. This plugin closes current PHP session and thus removes customer data from session storage. This happens only if page is fully cacheable (and it actually is).
Page is considered to be cacheable by page cache module only if its layout does not contain blocks with cacheable="false"
. Adding this attribute will not make this block loaded by Ajax (as assumed in the question). To have some block being loaded by Ajax, this block should have declared property _isScopePrivate
which is set to true
, moreover, there should be no blocks with cacheable="false"
on the page. See \Magento\PageCache\Observer\ProcessLayoutRenderElement::execute()
and mage.pageCache._replacePlaceholder()
in Magento/PageCache/view/frontend/web/js/page-cache.js. Also check high-level docs in page cache module readme
Product page should not be cacheable since cacheable="false"
is set for checkout block, however it is, due to known issue Uncacheable blocks being cached. Until this issue is resolved, the following workaround may be used (don't ask me why it works, it is a long story):
- Go to
\Magento\Framework\Pricing\Render\Layout::__construct
- Change
['cacheable' => $generalLayout->isCacheable()]
to ['cacheable' => false]
This should not harm because product pages will not be cached anyway after adding checkout block
Another question is, do you really want to make product pages non-cacheable by built-in page cache or Varnish?