Magento
CMS Bundle (Blocks & Pages)
A headless storefront needs your CMS blocks (header strips, promos, footers) and pages
(about, policies, landing pages) — but fetching them one-by-one over the standard GraphQL is
slow and leaves {{media}} directives unresolved. CMS Bundle returns all of them in a
single call, with directives already resolved to absolute (or CDN) URLs, HTML sanitised, a
deduplicated list of every referenced image, and a version hash so the storefront knows when
to re-fetch.

Compatibility
Section titled “Compatibility”PHP
Multi-store
Safe
One call, the whole CMS
Section titled “One call, the whole CMS”{ cmsBlockBundle { version count image_count blocks { identifier title content is_active update_time } images { url referenced_by } } }Every active block for the store, content fully resolved + sanitised.
{ cmsPageBundle { version count pages { identifier title content meta_title meta_description page_layout is_active } images { url referenced_by } } }The whole CMS page tree, ready to render client-side.
{ cmsBlockSingle(identifier: "header_promo") { identifier content update_time } }{ cmsPageSingle(identifier: "about-us") { identifier content is_active } }Surgical per-item refresh after a merchant edit — no full-bundle re-fetch.
What it does to the content
Section titled “What it does to the content”-
Resolves directives —
{{media url=...}},{{store url=...}}and nested{{block id=...}}become absolute URLs (a missing/broken directive falls back to raw content with a log, never crashing the bundle). -
Sanitises HTML (when enabled) — strips inline styles/classes/IDs and Word/MSO junk, and rewrites CMS block-embed directives to
<div data-cms-block-id="…">placeholders your storefront renders. -
Rewrites media to your CDN (when configured) — every
/pub/media/URL points at your storefront’s image CDN instead of Magento. -
Extracts every image into a deduplicated list with which blocks/pages reference each one — so your storefront can pre-fetch and rehost them, and a missing image is traceable.
-
Stamps a version hash — timestamp + sha1 of all content, so the storefront re-fetches only when something actually changed.
Security: drafts stay private
Section titled “Security: drafts stay private”Why a bundle instead of the standard cmsBlocks query?
Speed and completeness. One store-scoped DB round-trip returns every block with directives already
resolved, versus the standard resolver querying scope per identifier and leaving {{media}}
placeholders for you to resolve. Your storefront pre-warms a content cache once and serves CMS
chrome instantly.
How does my storefront know when to refresh?
Compare the version hash. It changes only when block/page content or timestamps change, so the
storefront re-fetches the bundle just when needed — and cmsBlockSingle / cmsPageSingle let a
webhook patch a single item without a full refresh.
Can each store view have different CMS content?
Yes — every query is store-scoped (store_id, defaulting to the request’s store), so a UK and a
DE store view each get their own correctly-scoped block and page set.
Is the HTML safe to render?
When the sanitiser is enabled, content is run through an allow-list that strips inline styles/classes and editor junk and normalises embed directives — so what reaches your storefront is clean, predictable HTML. Verified clean on PHP 8.4 and 8.5.