Forms: Fix boot script timing with third-party plugins that use script modules#47823
Forms: Fix boot script timing with third-party plugins that use script modules#47823
Conversation
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! |
2c9a3e0 to
0f28c4e
Compare
Code Coverage SummaryCoverage changed in 1 file.
Full summary · PHP report · JS report If appropriate, add one of these labels to override the failing coverage check:
Covered by non-unit tests
|
The wp-build generated page-wp-admin.php uses import("@wordpress/boot")
inside a regular inline script. This relies on the browser importmap
being in the DOM before the inline script executes. However, WordPress
outputs the importmap AFTER regular footer scripts (position 107 vs 100
in the DOM), making it fragile — it works by accident in most setups
due to browser microtask timing.
Plugins like The Events Calendar (via StellarWP) disrupt this timing by
converting scripts to type="module" via script_loader_tag, causing the
import() call to fail and leaving the Forms dashboard as a black screen.
Fix: Replace the inline import() with a two-step approach:
1. A plain global config (window.__jetpackFormsBootConfig) set by the
regular inline script — no module specifiers needed.
2. An inline <script type="module"> printed at priority 20 of
admin_print_footer_scripts (after the importmap at priority 9),
which imports @wordpress/boot and calls initSinglePage with the
config — guaranteed to resolve because modules execute after the
importmap.
The upstream fix will go into @wordpress/build's page-wp-admin.php
template to fix this for all consumers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
0f28c4e to
9b21253
Compare
Resolves FORMS-667
Note upstream fix WordPress/gutenberg#76870
Description
The wp-build generated
page-wp-admin.phpattaches animport("@wordpress/boot")call to a classic inline script viawp_add_inline_script. Inadmin_print_footer_scripts, both_wp_footer_scripts(classic scripts) andprint_import_maprun at priority 10, but_wp_footer_scriptsis registered first — so the inlineimport()executes before the import map is in the DOM.This is a latent bug: bare specifier resolution requires the import map to already exist. It happens to work in most environments because browser microtask scheduling defers the actual resolution. But when a third-party plugin (e.g. The Events Calendar, via StellarWP) converts classic scripts to
type="module"usingscript_loader_tag, the timing changes and@wordpress/bootfails to resolve — resulting in a blank Forms dashboard.Fix
Move the
import("@wordpress/boot")inline code from the classic script handle to a<script type="module">printed atadmin_print_footer_scriptspriority 20, well after the import map (priority 10). Module scripts resolve bare specifiers using whatever import map is in the DOM at execution time, so the ordering is guaranteed.The fix extracts the existing inline script verbatim — it doesn't reconstruct the boot config or depend on any
@wordpress/bootinternals.The upstream fix is WordPress/gutenberg#76870.
Does this pull request change what data or activity we track or use?
No
Testing instructions:
TypeError: Failed to resolve module specifier '@wordpress/boot'