What is Private Content?
Private Content Definition
Private content is user-specific data that cannot be cached globally:
- Shopping cart contents
- Wishlist items
- Recently viewed products
- Customer account data
- Compare products list
How Private Content Works
1. Page served from FPC (cached HTML)
2. JavaScript detects private sections needed
3. AJAX request to /customer/section/load/
4. Response contains user-specific HTML
5. JavaScript replaces placeholders in DOM
Sections Configuration
// customer-data.js manages sections
var sections = ['cart', 'wishlist', 'compare', 'recently-viewed'];
Section Loading
// /customer/section/load/?sections=cart,wishlist
// Returns JSON with HTML for each section
{
"cart": {
"html": "<div class='minicart'>...</div>",
"summary_count": 5,
"subtotal": 100.00
},
"wishlist": {
"html": "<div class='wishlist'>...</div>",
"counter": 3
}
}
Customer Sections Implementation
Section Provider Interface
namespace Vendor\Module\CustomerData;
use Magento\Customer\CustomerData\SectionInterface;
class CustomSection implements SectionInterface
{
public function __construct(
private \Magento\Customer\Model\Session $session
) {}
public function getSectionData(): array
{
return [
'custom_data' => $this->getCustomData(),
'counter' => $this->getCounter()
];
}
}
Register Section
<!-- etc/frontend/sections.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
<section id="custom"
label="Custom Section"
instance="Vendor\Module\CustomerData\CustomSection"/>
</config>
JavaScript Section Loading
// customer-data.js
require(['Magento_Customer/js/customer-data'], function(customerData) {
// Load specific sections
customerData.reload(['cart', 'custom'], true);
// Get section data
var cart = customerData.get('cart');
console.log(cart().summary_count);
});
Section Invalidation
// Invalidate section after action
$this->sectionPool->getSection('cart')->invalidate();
Section API
REST API Endpoint
GET /rest/V1/customers/section/load?sections=cart
Response:
{
"cart": {
"items_qty": 5,
"subtotal": 100.00,
"items": [...]
}
}
GraphQL Sections
query {
cart(cart_id: "...") {
items {
product { name }
quantity
}
prices { grand_total { value } }
}
}
Section Data Flow
// 1. Action triggers section update
$this->cart->addProduct($product);
// 2. Section marked as invalid
$this->sectionPool->getSection('cart')->invalidate();
// 3. AJAX request fetches updated section
// GET /customer/section/load/?sections=cart
// 4. Response contains fresh HTML
{
"cart": { "html": "...", "summary_count": 6 }
}
Section Expiration
// Section data TTL
'customer' => [
'ttl' => 3600 // 1 hour
]
Dynamic Blocks with FPC
Making Blocks Dynamic
// In block constructor
public function __construct(
// ...
array $data = []
) {
$data['cacheable'] = false;
parent::__construct($context, $data);
}
AJAX-Based Dynamic Blocks
<!-- Template -->
<div id="dynamic-content" data-mage-init='{"Magento_Ui/js/view/messages": {}}'>
<span class="loading">Loading...</span>
</div>
<script type="text/x-magento-init">
{
"#dynamic-content": {
"Magento_Ui/js/view/messages": {
"messageContainer": "<?php echo $block->getMessageContainer(); ?>"
}
}
}
</script>
Section-Based Dynamic Content
// Block that loads via section API
class MiniCart extends Template
{
public function getSectionData(): string
{
return $this->json->serialize([
'cart' => $this->cartData->getSummarySectionData()
]);
}
}
Best Practices
- Use section API for customer-specific data
- Minimize non-cacheable blocks
- Prefer AJAX over ESI for simplicity
- Cache section responses with short TTL
- Invalidate sections on relevant actions
Practice Problems
Design a private content solution for a product page with dynamic add-to-cart, wishlist, and review form.
Quiz
1. What is private content in Magento?
2. How does Magento load private content?
3. What interface do section providers implement?
4. How do you register a custom section?
Flashcards
Question
What is private content?
Click to reveal answer
Answer
User-specific data like cart, wishlist, and customer sections
Question
How does Magento load private content?
Click to reveal answer
Answer
AJAX to /customer/section/load/?sections=cart,wishlist
Question
What interface do sections implement?
Click to reveal answer
Answer
Magento\Customer\CustomerData\SectionInterface
Question
How to register a custom section?
Click to reveal answer
Answer
Define in etc/frontend/sections.xml
Question
How to invalidate a section?
Click to reveal answer
Answer
$this->sectionPool->getSection('cart')->invalidate()
Revision Notes
Key Takeaways
- 1. Private content is user-specific data that cannot be cached globally
- 2. Magento loads private content via AJAX to /customer/section/load/
- 3. Sections implement SectionInterface with getSectionData() method
- 4. Register sections in etc/frontend/sections.xml
- 5. Set cacheable=false for dynamic blocks within FPC
- 6. Invalidate sections after relevant user actions
Interview Tips
- • Explain the private content loading flow with FPC
- • Describe how to create custom customer sections
- • Discuss AJAX vs ESI for loading private content
- • Know the section API endpoint and response format
Cheat Sheet
Private Content Cheat Sheet
Flow:
- FPC serves cached HTML
- JS detects private sections
- AJAX to /customer/section/load/
- Response with user-specific HTML
- JS replaces DOM placeholders
Section:
implements SectionInterface {
getSectionData(): array
}
Register:
etc/frontend/sections.xml
Invalidate:
$sectionPool->getSection('cart')->invalidate()
Dynamic block:
$data['cacheable'] = false