WordPress 6.7 (released November 2024) brought a stable Font Library, expanded Block Hooks with position options, the HTML API gaining a processor for HTML5 elements, and the new wp_maybe_load_block_editor_scripts_and_styles() loading strategy. These changes affect how plugin developers handle fonts, block enhancements, and editor performance.
Problem: A WordPress site is running an older version and the upgrade changelog for 6.7 is unclear about which features require theme or plugin code changes versus which are automatic improvements.
Solution: WordPress 6.7 introduces an improved Font Library (persistent font management from the editor), Block Hooks second iteration (hooks into patterns and synced patterns), and HTML API tag processor updates. The Block Hooks change is the most impactful: blocks auto-inserted via block_hooks in block.json now also inject into block patterns and template parts, not just templates.
The examples below use the Font Library REST API to install fonts programmatically, register a Block Hook with the new first-child/last-child position, and use the improved HTML API Processor for safe template manipulation.
[
'name' => 'My Brand Font',
'slug' => 'my-brand-font',
'fontFamily' => '"My Brand Font", sans-serif',
],
'font_face_settings' => [
[
'fontFamily' => '"My Brand Font"',
'fontWeight' => '400',
'fontStyle' => 'normal',
'src' => [ get_template_directory_uri() . '/fonts/my-brand-font-regular.woff2' ],
],
[
'fontFamily' => '"My Brand Font"',
'fontWeight' => '700',
'fontStyle' => 'normal',
'src' => [ get_template_directory_uri() . '/fonts/my-brand-font-bold.woff2' ],
],
],
],
] );
} );
// WordPress 6.7: Block Hooks — new 'first-child' and 'last-child' positions
// Previously only 'before' and 'after' (sibling insertion) were available.
add_filter( 'hooked_block_types', function( array $hooked_blocks, string $position, string $anchor_block, $context ): array {
// Inject a 'core/spacer' as the FIRST child of every group block
if ( 'core/group' === $anchor_block && 'first-child' === $position ) {
$hooked_blocks[] = 'myplugin/top-badge';
}
// Inject a disclaimer block as the LAST child of every post content area
if ( 'core/post-content' === $anchor_block && 'last-child' === $position ) {
$hooked_blocks[] = 'myplugin/disclaimer';
}
return $hooked_blocks;
}, 10, 4 );
Use the WordPress 6.7 HTML API Processor for safe HTML transformation:
next_tag( 'img' ) ) {
// Skip images that already have explicit loading attribute
if ( $processor->get_attribute( 'loading' ) ) continue;
// Skip small hero images (above the fold — don't lazy-load)
$classes = $processor->get_attribute( 'class' ) ?? '';
if ( str_contains( $classes, 'hero-image' ) ) continue;
$processor->set_attribute( 'loading', 'lazy' );
$processor->set_attribute( 'decoding', 'async' );
}
return $processor->get_updated_html();
}
add_filter( 'the_content', 'myplugin_add_loading_lazy' );
// WP_HTML_Processor (6.4+, improved in 6.7) — understands nesting
function myplugin_wrap_tables( string $html ): string {
$processor = WP_HTML_Processor::create_fragment( $html );
if ( ! $processor ) return $html;
// Walk the HTML tree
while ( $processor->next_tag() ) {
if ( 'TABLE' !== $processor->get_tag() ) continue;
if ( $processor->get_attribute( 'data-wrapped' ) ) continue;
$processor->set_attribute( 'data-wrapped', 'true' );
// In WP 6.7 you can also get breadcrumbs: $processor->get_breadcrumbs()
}
return $processor->get_updated_html();
}
add_filter( 'the_content', 'myplugin_wrap_tables' );
NOTE: WordPress 6.7 also improved the Interactivity API's server-side rendering performance and added wp_interactivity_process_directives() for use outside block rendering. Update your block.json "requiresVersion" field to "6.7" if you use Block Hooks with first-child/last-child, as older WordPress versions will ignore those positions.