Magento Series: Working with CMS Blocks

CMS blocks are snippets of HTML code that can be used to easily add repeating content to pages and other blocks.

CMS blocks have 5 general properties:

  • Title – how you will see the CMS block in the Admin Panel block lists
  • Identifier – the key that will be used in code to reference this CMS block
  • Store views – define the scope in which this CMS block can be used
  • Status – a boolean field that determines if the block is enabled or not
  • Content – the HTML code used in the CMS block, that which will be displayed on the page

How to work with CMS blocks in the M2 backend?

To access a list of all CMS blocks, go to the Magento Admin Panel → tab Content → Blocks.

You can add new CMS blocks with the Add New Block button, or edit an existing one by selecting the Edit option from the block’s Action column.

To create a CMS block, you will need to define its title and identifier. To add content to your CMS block, you have multiple options:

  • Page Builder is the standard option that is enabled from the start. It gives you a wide range of tools to create CMS content without needing to write any code.
  • If you deactivate Page Builder, you can use the WYSIWYG editor. It is useful for previewing what the CMS block will look like and inserting images, other CMS blocks, or widgets.
  • By clicking the Show / Hide Editor button, you can switch between the WYSIWYG editor and the raw HTML text area, where you can directly edit the HTML content.

When you have created and saved your block, you can add it to CMS pages, other CMS blocks, or render it in React.

Where is CMS block data stored?

CMS blocks are stored in the MySQL server database in the cms_block table. The relations between CMS blocks and stores are saved in the cms_block_store table.

How to render a CMS block in ScandiPWA?

ScandiPWA is the first open source PWA theme for Magento (Adobe Commerce). It is the fastest way to get ready-to-use PWA for any Magento website.

CMS blocks are rendered in ScandiPWA as React components. A data container holds the React component and the CMS block’s data that it gets through GraphQL.

How to render a CMS block?

The simplest way to render a CMS block in a React component is to use a render method that returns a CmsBlock component with an identifier argument. The identifier determines what CMS block is rendered.

import CmsBlock from 'Component/CmsBlock';
import { Component } from 'react';
//...
export class Lion extends Component {
	render() {
		return (
			<CmsBlock identifier="lion"/>
		)
	}
}

An example of a preexisting CMS block render method from the ContactPage.component script:

renderCmsBlock() {
    const {
        contact_us_content: {
            contact_us_cms_block = 'contact_us_page_block'
        } = {}
    } = window.contentConfiguration;

    return <CmsBlock identifier={ contact_us_cms_block } />;
}

➡️ This renders the contact information block in the Contact Page. It can have dependencies on other data or schema patches.

How can CMS content be configured for PWA in the Admin Panel?

window.contentConfiguration is a JavaScript object that contains the basic configuration for frontend content rendering, passed from the backend to the frontend. It identifies things such as what the footer CMS block identifier is.

In the CMS block context, it is used to define identifiers of common base template CMS blocks, e.g., the page footer:

const { footer_content: { footer_cms } = {} } = window.contentConfiguration.

window.contentConfiguration value is prepared during the ScandiPWA theme build. The values are taken from the Admin Panel system configuration: Store → Configuration → ScandiPWA → Content customization.

In Content customization, you can change what blocks are used in the frontend content rendering without changing the code.

How to debug problems with the CMS block render?

If a block is not rendering for an unknown reason, the browser dev tools Network tab can be a good place to check first.

The container gets the CMS block content based on the block’s identifier through GraphQL.

A failed GraphQL query can show a failure(non-200) status as a response, or an incorrect response, containing some relevant error information.

A missing GraphQL query would mean that the block is not being attempted to be loaded at all, indicating that the issue is with the theme part that initiates the display of the block.

➡️ The rendering code is located in the project’s theme: <project-name>/scandipwa/node_modules/@scandipwa/scandipwa/src/component/CmsBlock/ CmsBlock.component.js and CmsBlock.container.js.

➡️ The code that gets the CMS block’s data is located in <project-name>/scandipwa/node_modules/@scandipwa/scandipwa/src/query/CmsBlock.query.js.

How to localize CMS block content?

The standard way to localize CMS block content is to create a separate instance for each locale.

CMS blocks need to have a unique identifier on a store level. This means that you can use the same identifier on multiple stores, and each of those block instances can have a unique title and content.

When requesting the CMS block from the frontend, the version for the current store will be loaded.

If the CMS block is defined by using contentConfiguration, it is also possible to set store-specific configuration on which CMS block to use.

To translate a single string in the CMS block, you can also use Magento inline translations {{trans "some text"}} in the CMS block content. If this approach is used, translations have to be added to the backend *.csv translation files.

How to display CMS blocks in a default theme?

Theme-specific frontend layout changes to the default theme are usually located in <project-name>/app/design/frontend/<theme-name>/layout.

The CMS block itself is a block element that has (1) a class property from where the block’s data will be retrieved and (2) a name, which is usually the same as the identifier.

The block element contains an arguments element that lists argument elements. A CMS block should have a name="block_id" argument that contains the CMS block identifier.

🔍 To find what view can be edited, look in <project-name>/vendor/magento/module-catalog/view/frontend/layout. Copy the name and page element properties.

Simple XML example:

<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
	<body>
		<!-- the name property will determine, in what container the block will be placed -->
		<referencedContainer name="page.top">
			<block class="Magento\Cms\Block\Block" name="lion">
				<arguments>
					<!-- 
						The name and type define what argument is being changed.
						Block_id is the argument used to specify an identifier for the CMS block.
						The value here - 'lion' - is what is actually referencing the block.
					-->
					<argument name="block_id" xsi:type="string">lion<argument/>
				</arguments>
			</block>
		</referencedContainer>
	</body>
</page>

➡️ For an example of how to add a display of a CMS block to a PDP in a default (non-PWA) Magento theme, you can watch this video: Add a CMS block to the product description page in Magento 2.

Need help with Magento (Adobe Commerce) development? scandiweb is the largest certified Magento developer team in the world. Ask us how you can get a dedicated eCommerce team and get the hassle out of web development, design, and the whole eCommerce optimization process. Or send us a message about your specific needs.

If you enjoyed this post, you may also like