Skip to content

fix: print WordPress 7 block styles in the head of Blade pages - #379

Merged
ogorzalka merged 1 commit into
developfrom
fix/hoist-late-styles
Oct 2, 2026
Merged

ogorzalka merged 1 commit into
developfrom
fix/hoist-late-styles

Conversation

@ogorzalka

Copy link
Copy Markdown
Member

Problem

Under WordPress 7, a classic theme loads block styles on demand: they are printed at wp_footer, once the page's blocks are known, then wp_hoist_late_printed_styles() moves them — global-styles included — back into the <head> through the template enhancement output buffer.

WordPress only starts that buffer at wp_before_include_template, in template-loader.php. Pollora renders Blade views into a Laravel response and never includes a template, so on every Blade page:

  • global-styles and the block styles (wc-blocks-style…) were printed just before </body>, after the content they style (FOUC on slow connections);
  • the head kept two empty placeholders (wp-block-styles-placeholder, wp-global-styles-placeholder).

Measured on pollora-test (Apiary, WordPress 7.1.2) before the fix.

Fix

A WordPressTemplateEnhancement middleware, last in WORDPRESS_MIDDLEWARE (so Route::wp() and the template hierarchy), plays the buffer's part on the response instead of PHP's output:

  • wp_template_enhancement_output_buffer_started before the view renders (this is what hooks the hoisting);
  • wp_template_enhancement_output_buffer filter + wp_finalized_template_enhancement_output_buffer action on the HTML content.

WordPress's own wp_should_output_buffer_template_for_enhancement() decides, so a site that opted out (to stream) is untouched. JSON, redirects, streamed and binary responses are left alone; a throwing callback is reported and the page sent as rendered, like core. Any plugin built on that filter now sees Pollora's pages too.

Plain Laravel routes do not get the WordPress stack; one that prints wp_head()/wp_footer() can add the middleware itself (noted in the CHANGELOG).

Tests

  • Unit: WordPressTemplateEnhancementTest (7 cases). Full suite 1382 passed, PHPStan, Pint, Rector, type coverage 99 % (new file 100 %).
  • E2E: styles.spec.ts publishes a post with a separator block and asserts that its style and global-styles are in the head, with no placeholder left. Fails without the middleware, passes with it (checked locally).
  • After the fix on pollora-test: no style left in the body and no placeholder on home, shop, post, page, search and 404.

@ogorzalka
ogorzalka merged commit bb10b0d into develop Oct 2, 2026
11 checks passed
@ogorzalka
ogorzalka deleted the fix/hoist-late-styles branch October 2, 2026 15:19
This was referenced Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant