apply_filters( ‘render_block’, string $block_content, array $block, WP_Block $instance )

Filters the content of a single block.


The block content.
The full block, including name and attributes.
The block instance.


$block_content = apply_filters( 'render_block', $block_content, $this->parsed_block, $this );


5.9.0The $instance parameter was added.

User Contributed Notes

  1. Skip to note 5 content

    To add a div wrapper outside of some blocks (like core/paragraph or core/heading), you can add filter to render_block:

    // functions.php
    function wporg_block_wrapper( $block_content, $block ) {
    	if ( $block['blockName'] === 'core/paragraph' ) {
    		$content = '<div class="wp-block-paragraph">';
    		$content .= $block_content;
    		$content .= '</div>';
    		return $content;
    	} elseif ( $block['blockName'] === 'core/heading' ) {
    		$content = '<div class="wp-block-heading">';
    		$content .= $block_content;
    		$content .= '</div>';
    		return $content;
    	return $block_content;
    add_filter( 'render_block', 'wporg_block_wrapper', 10, 2 );
  2. Skip to note 6 content

    (array) The full block, including name and attributes.

    Good to know that $block['attrs'] do not include attributes declared in block.json with “source” set to “attribute”.

    For example, in a block.json :

    "attributes": {
        "url": {
            "type": "string",
            "source": "attribute",
            "selector": "a",
            "attribute": "href"
        "width": {
            "type": "number"

    $block['attrs'] only include width, not url.

  3. Skip to note 7 content

    Here’s a quick/rough example of how you can render any block in any way with this filter. Note that the example uses an attribute called `name_of_attribute_here`. You’ll want to use an actual attribute that belongs to that block.

    A quick/easy way to discover what’s available to you is to `print_r( $block );` inside the function, refresh the frontend page where the block sits, and see what’s available in the `attrs`.

     * Modify the rendered output of any block.
     * @param string $block_content The normal block HTML that would be sent to the screen.
     * @param array  $block An array of data about the block, and the way the user configured it.
    function my_custom_render( $block_content, $block ) {
    	// For the block in question, render whatever you want, and pull any attrinute you need from $block['attrs'].
    	if ( $block['blockName'] === 'core/image' ) {
    		return 'Anything I want with any attribute value here: ' . $block['attrs']['name_of_attribute_here'] . '.';
    	// For any other block, just return normal block output.
    	return $block_content;
    add_filter( 'render_block', 'my_custom_render', 10, 2 );
  4. Skip to note 8 content

    $block_content and $block can become null, so be sure to handle these cases.

    function wpdocs_render_block( $block_content, $block ) {
    	if ( is_null( $block_content ) ) {
    		// Handle null
    	if ( isset( $block['blockName'] ) && 'wpdocs/block' === $block['blockName'] ) {
    		// Do something
    	return $block_content;
    add_filter( 'render_block', 'wpdocs_render_block', 10, 2 );

You must log in before being able to contribute a note or feedback.