A block pattern is markup registered in PHP

A layout that editors kept rebuilding by hand was being solved with a custom block, which needs JavaScript, a build step and a plugin. A pattern is a string.

add_action( 'init', function () {
    register_block_pattern( 'turkerdev/two-column-cta', array(
        'title'       => __( 'Two-column call to action', 'turkerdev' ),
        'categories'  => array( 'turkerdev' ),
        'description' => _x( 'Heading and text beside a button.', 'Block pattern description', 'turkerdev' ),
        'content'     => '<!-- wp:columns --><div class="wp-block-columns">'
            . '<!-- wp:column --><div class="wp-block-column">'
            . '<!-- wp:heading --><h2>Ready?</h2><!-- /wp:heading -->'
            . '</div><!-- /wp:column --></div><!-- /wp:columns -->',
    ) );
} );

The content is block markup, which is why it needs no JavaScript at all — the editor parses it exactly as it would parse a saved post. Writing that markup by hand is unpleasant, and the practical route is to build the layout in the editor, open the code view and copy it. The escaping is the part that catches people: the markup goes into a PHP string, so quotes have to survive and a heredoc reads considerably better than concatenation.