Gutenberg First Block on Page Conditional?

Here’s a solution I’ve come up with, that works with WordPress 5.4 and ACF Pro 5.8.9.

First you need this function somewhere in functions.php:

/**
 * Get ID of the first ACF block on the page
 */
function sg_get_first_block_id() {
    $post = get_post(); 

    if(has_blocks($post->post_content)) {
        $blocks = parse_blocks($post->post_content);
        $first_block_attrs = $blocks[0]['attrs'];

        if(array_key_exists('id', $first_block_attrs)) {
            return $first_block_attrs['id'];
        }
    }
}

This function is used to get the block id of the first block on the page, if this block has a block id. (As far as I can see only ACF blocks have a block id attribute. Core blocks do not).

Now in your block template file you can do this:

<?php if($block['id'] === sg_get_first_block_id()): ?>
    <h1><?php the_title(); ?></h1>
<?php endif; ?>

$block['id'] is the unique id of every block instance. We then compare it with the id of the first block on the page. If they’re the same, the function will return true, and the title of the post will be displayed.

How i use it

I have created a custom cover block with a full size background image and content inside. I wan’t that block to act as a hero element if it’s the very first block on a page.

By using the above method in my block template file, I can display the custom cover block title in a h1 tag instead of h2, if it’s the first block on the page.

<?php if($block['id'] === sg_get_first_block_id()): ?>
    <h1><?php echo $title; ?></h1>
<?php else: ?>
    <h2><?php echo $title; ?></h2>
<?php endif; ?>

I also wan’t to hide the ordinary title and breadcrumb, so that the cover block aligns perfectly to the navigation header. For that I have created this function in my functions.php file:

/**
 * Check first block type
 * @param string block_handle - handle of the block
 */
function sg_first_block_is($block_handle) {
    $post = get_post(); 

    if(has_blocks($post->post_content)) {
        $blocks = parse_blocks($post->post_content);

        if($blocks[0]['blockName'] === $block_handle) {
            return true;
        }else {
            return false;
        }
    }
}

I can use this as a conditional to check what block type the first block is, and then display or hide the breadcrumb and title accordingly:

if(!sg_first_block_is('acf/sg-cover')):
    get_template_part('template-parts/components/component', 'breadcrumbs'); 
    echo '<h1>' . get_the_title() . '</h1>';
endif;