Block-based Widget Areas

The next phase of Gutenberg includes bringing the block editor to the Widgets screen. But we’re building websites that need this functionality right now.

I’ve come up with a simple solution for using the block editor outside of the main content area, in contexts where we used to use widget areas.

Register a Block Area post type

I create a custom post type called “Block Area”, and each unique block area is a post. To display the block area, we query for the block_area post with a specific slug and display its contents.

I built it as a class that I include in our core functionality plugin. To display the after-post block area, I add this to my theme’s single.php file:

if( function_exists( 'ea_block_area' ) ) ea_block_area()->show( 'after-post' );

Once WordPress core adds block-based widget areas, I can migrate the block content from my block_area post type to whatever WordPress core uses, and update the show() method to use dynamic_sidebar() or a new function in WP core.


I’m working on a website with an “After Post” block area for blocks that appear at the end of every article.

Code for Block Areas

I recommend including this in a core functionality plugin. You can then use the ea_block_area() function in your theme after checking if the function exists.

<?php /** * Block Area * CPT for block-based widget areas, until WP core adds block support to widget areas * @link * * @package CoreFunctionality * @author Bill Erickson * @since 1.0.0 * @license GPL-2.0+ **/ class EA_Block_Area { /** * Instance of the class. * @var object */ private static $instance; /** * Class Instance. * @return EA_Block_Area */ public static function instance() { if ( ! isset( self::$instance ) && ! ( self::$instance instanceof EA_Block_Area ) ) { self::$instance = new EA_Block_Area(); // Actions add_action( 'init', array( self::$instance, 'register_cpt' ) ); add_action( 'template_redirect', array( self::$instance, 'redirect_single' ) ); } return self::$instance; } /** * Register the custom post type * */ function register_cpt() { $labels = array( 'name' => 'Block Areas', 'singular_name' => 'Block Area', 'add_new' => 'Add New', 'add_new_item' => 'Add New Block Area', 'edit_item' => 'Edit Block Area', 'new_item' => 'New Block Area', 'view_item' => 'View Block Area', 'search_items' => 'Search Block Areas', 'not_found' => 'No Block Areas found', 'not_found_in_trash' => 'No Block Areas found in Trash', 'parent_item_colon' => 'Parent Block Area:', 'menu_name' => 'Block Areas', ); $args = array( 'labels' => $labels, 'hierarchical' => false, 'supports' => array( 'title', 'editor', 'revisions' ), 'public' => false, 'show_ui' => true, 'show_in_rest' => true, 'exclude_from_search' => true, 'has_archive' => false, 'query_var' => true, 'can_export' => true, 'rewrite' => array( 'slug' => 'block-area', 'with_front' => false ), 'menu_icon' => 'dashicons-welcome-widgets-menus', ); register_post_type( 'block_area', $args ); } /** * Redirect single block areas * */ function redirect_single() { if( is_singular( 'block_area' ) ) { wp_redirect( home_url() ); exit; } } /** * Show block area * */ function show( $location = '' ) { if( ! $location ) return; $location = sanitize_key( $location ); $loop = new WP_Query( array( 'post_type' => 'block_area', 'name' => $location, 'posts_per_page' => 1, )); if( $loop->have_posts() ): while( $loop->have_posts() ): $loop->the_post(); echo '<div class="block-area block-area-' . $location . '">'; the_content(); echo '</div>'; endwhile; endif; wp_reset_postdata(); } } /** * The function provides access to the class methods. * * Use this function like you would a global variable, except without needing * to declare the global. * * @return object */ function ea_block_area() { return EA_Block_Area::instance(); } ea_block_area();

Bill Erickson

Bill Erickson is a freelance WordPress developer and a contributing developer to the Genesis framework. For the past 14 years he has worked with attorneys, publishers, corporations, and non-profits, building custom websites tailored to their needs and goals.

Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions


    • Bill Erickson says

      Very cool! I haven’t seen that before. That seems to be a great way to get blocks into existing widget areas.

  1. Joris Kroos says

    Pretty neat function;

    The code “$page = get_the_ID() ? get_the_ID() : $_POST[‘post_id’];”

    Which you advised on the header block, doesn’t work combined with the block area’s, returning the ID of the block area instead.

    Seems the block area’s won’t do any good when trying to fetch content based on acf values of the main post. How does your Display Posts shortcode solve this?

    • Bill Erickson says

      Use `get_queried_object_id()` instead, which returns the ID of the queried object (ex: post ID when viewing a single post) regardless of any custom loops you may be in currently.

  2. Victor Ramirez says

    How are you handling user registration & creation of block areas?

    I like that you create a CPT similar to your category landing pages plugin. Great for admin use.

    If someone hits “add new” how are they assigning it to a specific area? Or are you only recognizing ‘block areas’ that you create and restricting users from ‘add new’?

    • Bill Erickson says

      I’m not preventing users from creating new block areas, although it probably would be a good idea because user-generated block areas won’t appear anywhere on the site.

  3. David Smyth says

    This is awesome thank you. I recommend tacking on a shortcode so this can be easily added in a sidebar widget, simply:

    add_shortcode(‘show-block-area’, function ($atts, $content = null) {
    $atts = shortcode_atts(array(
    ‘block’ => ”,
    ), $atts);


    • Bill Erickson says

      That’s an interesting way to use this functionality.

      Personally I use the block area as a replacement for the widget area, so I’ll replace the dynamic_sidebar( 'sidebar' ); with ea_block_area()->show( 'sidebar' );. But you could definitely use the block area inside the widget area with a shortcode.

Leave A Reply