Skip to content

Product Shell Bundle

A headless storefront that calls Magento GraphQL for every product page is slow and load-sensitive. Product Shell Bundle solves that by pre-building a “shell” for each product — all the slowly-changing data (name, description, media, attributes, variants, customizable options, categories, related products, reviews) plus indexed price and stock — into a paginated JSON snapshot and a matching GraphQL feed. Your storefront renders the page instantly from the shell, then overlays live price and stock for one product on hydration.

Sync Products — the shell bundle dashboard

Magento

Open Source 2.4.9 GA (and later 2.4.x).

PHP

Tested on 8.4 and 8.5.

Delivery

Paginated GraphQL feed + downloadable JSON snapshot.

Extensible

Other modules add per-product data via a contributor hook.

Each product shell carries everything a PDP needs to render without a second call:

GroupIncludes
Coresku, name, url_key, type, descriptions, meta fields
Mediabase/small/thumbnail/swatch images + full gallery
Commerceindexed price_range and stock_status (anonymous group)
Variantsconfigurable options + per-variant price/stock
Optionscustomizable options (drop-down, radio, field…) with prices
Relationscategory IDs, related/upsell/cross-sell SKUs
Social proofrating summary, review count, recent approved reviews
Type extrasbundle / grouped / downloadable specifics
{
productShellBundle(page_size: 100, current_page: 1) {
total_count total_pages current_page
products { sku name type_id stock_status
price_range { minimum_price { final_price { value currency } } } }
categories { category_id name url_path }
}
}

Paginated (page size capped for safety) so you can warm your storefront cache page by page.

Only enabled products

Both the bundle and the single-product feed return enabled products only — a disabled product never leaks into the snapshot or via a guessed SKU.

Anonymous-accurate pricing

Price and stock are read from Magento’s price index and MSI stock view for the NOT LOGGED IN group, so the shell matches what an anonymous shopper sees — your storefront overlays customer-specific pricing live.

Approved reviews only

Embedded reviews are the most recent approved ones, store-scoped — ready for the reviews block and aggregateRating JSON-LD.

Safe downloads

The admin JSON download is permission-gated and the store code is sanitised, so the snapshot path can’t be manipulated.

Why a shell plus live overlay, instead of just calling GraphQL?

Most product data barely changes between catalogue edits, so serving it from a pre-warmed snapshot makes PDPs render instantly. Only the volatile bits — price and stock — are fetched live per product on hydration, which keeps pages both fast and accurate.

Will disabled products show up in the feed?

No — the bundle and the productShellSingle query both filter to enabled products, so a disabled product can’t appear in the snapshot or be pulled by guessing its SKU.

How do I refresh just one product after an edit?

Call productShellSingle(sku: …) (or your webhook handler does) to re-fetch that single shell in about 150 ms, rather than rebuilding the whole bundle.

Can other modules add data to each product shell?

Yes — a module can register a shell contributor that adds a keyed entry to each product’s extensions map, without modifying this module. A misbehaving contributor is logged and skipped, so it can never break the build. Verified clean on PHP 8.4 and 8.5.