Interactivity API best practices in 6.8

<div style&equals;"text-align&colon;center"><&sol;div><div>&NewLine;<p>WordPress 6&period;8 comes with a few new best practices and requirements in the Interactivity API that are part of a longer-term continuous-improvement effort&period; Some of the relevant changes in 6&period;8 are an intermediary step&colon; They do not include these enhancements themselves&comma; but they prepare the project to add them in a future release by adding two new deprecation warnings&period;<&sol;p>&NewLine;<p>If you have been using the Interactivity API in your project&comma; especially if you have been writing your own stores&comma; please read on to learn how you can prepare your changes for the latest and future behavior of the API&period;<&sol;p>&NewLine;<h2 class&equals;"wp-block-heading">How to apply the latest best practices &lpar;and avoid deprecation warnings&rpar;<&sol;h2>&NewLine;<p>To help the Interactivity API speed up WordPress&comma; the project is working towards running most store actions asynchronously by default&comma; as a better foundation for achieving good INP &lpar;&OpenCurlyDoubleQuote;Interaction to Next Paint”&rpar; performance&period; Right now&comma; browsers invoke all synchronous Interactivity API event handlers as part of the same task—this means they stack up&period; This can make the user wait for longer than 50 milliseconds &lpar;also called a <a href&equals;"https&colon;&sol;&sol;web&period;dev&sol;articles&sol;optimize-long-tasks">&OpenCurlyDoubleQuote;long task”<&sol;a>&rpar; for the site to react to some interaction&comma; like clicking a button&period;<&sol;p>&NewLine;<p>Starting with 6&period;8&comma; and going forward&comma; the Interactivity API’s push towards asynchronous handlers as the default will make those long tasks less likely&period; The 6&period;8 release only prepares for the transition&period; In the following WordPress release&comma; the API will automatically yield to the main thread in between handlers&comma; so ideally there’s nothing to stack up&comma; and nothing to make the user wait&period; &lpar;Also refer to <a href&equals;"https&colon;&sol;&sol;developer&period;wordpress&period;org&sol;block-editor&sol;reference-guides&sol;interactivity-api&sol;api-reference&sol;&num;&colon;~&colon;text&equals;&percnt;7D&percnt;20&rpar;&percnt;3B-&comma;Async&percnt;20actions&comma;-Async&percnt;20actions&percnt;20should">async actions<&sol;a> and the <a href&equals;"https&colon;&sol;&sol;developer&period;wordpress&period;org&sol;block-editor&sol;reference-guides&sol;interactivity-api&sol;api-reference&sol;&num;&colon;~&colon;text&equals;API&percnt;20provides&percnt;20the-&comma;splitTask&lpar;&rpar;&comma;-function&percnt;20for&percnt;20that"><code>splitTask&lpar;&rpar;<&sol;code> function<&sol;a>&period;&rpar;<&sol;p>&NewLine;<p>This performance enhancement also helps with cross-plugin compatibility&comma; as handlers for the same event may come from different plugins&period; The new requirements outlined below are an important step to prepare the Interactivity API for that future&period;<&sol;p>&NewLine;<h3 class&equals;"wp-block-heading">Wrap certain action callbacks in <code>withSyncEvent&lpar;&rpar;<&sol;code><&sol;h3>&NewLine;<p>Pay attention to any store action that is attached to an event listener &lpar;like <code>data-wp-on--click<&sol;code>&rpar; <em>and<&sol;em> accesses the <code>event<&sol;code> object&colon; If the action callback uses any of the <code>event<&sol;code> properties or methods below&comma; you need to wrap it in a newly added utility function called <code>withSyncEvent&lpar;&rpar;<&sol;code>&colon;<&sol;p>&NewLine;<ul class&equals;"wp-block-list">&NewLine;<li>Property&colon; <code>event&period;currentTarget<&sol;code><&sol;li>&NewLine;<li>Method&colon; <code>event&period;preventDefault&lpar;&rpar;<&sol;code><&sol;li>&NewLine;<li>Method&colon; <code>event&period;stopImmediatePropagation&lpar;&rpar;<&sol;code><&sol;li>&NewLine;<li>Method&colon; <code>event&period;stopPropagation&lpar;&rpar;<&sol;code><&sol;li>&NewLine;<&sol;ul>&NewLine;<p><strong>Starting in WordPress 6&period;8&comma; if any action callback uses the above <code>event<&sol;code> properties or methods and is not wrapped in <code>withSyncEvent&lpar;&rpar;<&sol;code>&comma; that action callback will trigger a deprecation warning&period;<&sol;strong> For now&comma; the logic will continue to work as before&period; But in a future WordPress release it will break if you do not migrate&period; For example&comma; <code>event&period;preventDefault&lpar;&rpar;<&sol;code> will not prevent the default action since the action will be asynchronous by default&period; As such&comma; please make sure to resolve any deprecation warnings you see&period;<&sol;p>&NewLine;<p>This <em>correct<&sol;em> &lpar;<imgsrc&equals;"" alt&equals;"✅" class&equals;"wp-smiley" style&equals;"height&colon; 1em&semi; max-height&colon; 1em&semi;">&rpar; code example illustrates how to use <code>withSyncEvent&lpar;&rpar;<&sol;code>&colon;<&sol;p>&NewLine;<div class&equals;"wp-block-syntaxhighlighter-code ">&NewLine;<pre class&equals;"brush&colon; jscript&semi; title&colon; &semi; notranslate">&NewLine;import &lbrace; store&comma; withSyncEvent &rcub; from '&commat;wordpress&sol;interactivity'&semi;&NewLine;&NewLine;store&lpar; 'myPlugin'&comma; &lbrace;&NewLine;&Tab;actions&colon; &lbrace;&NewLine;&Tab;&Tab;&sol;&sol; &grave;event&period;preventDefault&lpar;&rpar;&grave; requires synchronous event access&period;&NewLine;&Tab;&Tab;preventNavigation&colon; withSyncEvent&lpar; &lpar; event &rpar; &equals;> &lbrace;&NewLine;&Tab;&Tab;&Tab;event&period;preventDefault&lpar;&rpar;&semi;&NewLine;&Tab;&Tab;&rcub; &rpar;&comma;&NewLine;&NewLine;&Tab;&Tab;&sol;&sol; &grave;event&period;target&grave; does not require synchronous event access&period;&NewLine;&Tab;&Tab;logTarget&colon; &lpar; event &rpar; &equals;> &lbrace;&NewLine;&Tab;&Tab;&Tab;console&period;log&lpar; 'event target &equals;> '&comma; event&period;target &rpar;&semi;&NewLine;&Tab;&Tab;&rcub;&comma;&NewLine;&NewLine;&Tab;&Tab;&sol;&sol; Not using &grave;event&grave; at all does not require synchronous event access&period;&NewLine;&Tab;&Tab;logSomething&colon; &lpar;&rpar; &equals;> &lbrace;&NewLine;&Tab;&Tab;&Tab;console&period;log&lpar; 'something' &rpar;&semi;&NewLine;&Tab;&Tab;&rcub;&comma;&NewLine;&Tab;&rcub;&comma;&NewLine;&rcub; &rpar;&semi;&NewLine;<&sol;pre>&NewLine;<&sol;div>&NewLine;<p>This <em>bad<&sol;em> &lpar;<imgsrc&equals;"" alt&equals;"❌" class&equals;"wp-smiley" style&equals;"height&colon; 1em&semi; max-height&colon; 1em&semi;">&rpar; example will&comma; going forward&comma; emit a deprecation warning&colon;<&sol;p>&NewLine;<div class&equals;"wp-block-syntaxhighlighter-code ">&NewLine;<pre class&equals;"brush&colon; jscript&semi; title&colon; &semi; notranslate">&NewLine;import &lbrace; store &rcub; from '&commat;wordpress&sol;interactivity'&semi;&NewLine;&NewLine;store&lpar; 'myPlugin'&comma; &lbrace;&NewLine;&Tab;actions&colon; &lbrace;&NewLine;&Tab;&Tab;&sol;&sol; Missing &grave;withSyncEvent&lpar;&rpar;&grave; around synchronous event access&period;&NewLine;&Tab;&Tab;preventNavigation&colon; &lpar; event &rpar; &equals;> &lbrace;&NewLine;&Tab;&Tab;&Tab;event&period;preventDefault&lpar;&rpar;&semi;&NewLine;&Tab;&Tab;&rcub;&comma;&NewLine;&Tab;&rcub;&comma;&NewLine;&rcub; &rpar;&semi;&NewLine;<&sol;pre>&NewLine;<&sol;div>&NewLine;<h3 class&equals;"wp-block-heading">Do not use actions to determine HTML attribute values<&sol;h3>&NewLine;<p>If you have been relying on Interactivity API store functions &lpar;like <code>actions<&sol;code> or <code>callbacks<&sol;code>&rpar; to determine HTML attribute values &lpar;e&period;g&period; via <code>data-wp-bind--attr<&sol;code>&rpar;&comma; please revise these attributes now&period; Instead&comma; use <a href&equals;"https&colon;&sol;&sol;developer&period;wordpress&period;org&sol;block-editor&sol;reference-guides&sol;interactivity-api&sol;core-concepts&sol;undestanding-global-state-local-context-and-derived-state&sol;">global state&comma; local context&comma; or derived state<&sol;a>&period; And please do not combine these function calls with directive logic like the <code>&excl;<&sol;code> operator&period;<&sol;p>&NewLine;<p><strong>Starting in WordPress 6&period;8&comma; any directive using a store function in combination with the <code>&excl;<&sol;code> operator will emit a deprecation warning&period;<&sol;strong> The logic will continue to work as before for now&comma; but in a future WordPress release it will break if you do not migrate&period; More broadly&comma; if you are using store functions in directives that determine HTML attribute values&comma; please migrate to using <a href&equals;"https&colon;&sol;&sol;developer&period;wordpress&period;org&sol;block-editor&sol;reference-guides&sol;interactivity-api&sol;core-concepts&sol;undestanding-global-state-local-context-and-derived-state&sol;">global state&comma; local context&comma; or derived state<&sol;a> instead&period; More deprecation warnings around incorrect usage of store functions are expected soon&comma; and eventually unmigrated code is going to break&period;<&sol;p>&NewLine;<p>Please refer to the following <em>correct<&sol;em> &lpar;<imgsrc&equals;"" alt&equals;"✅" class&equals;"wp-smiley" style&equals;"height&colon; 1em&semi; max-height&colon; 1em&semi;">&rpar; code example to illustrate how to use derived state&colon;<&sol;p>&NewLine;<div class&equals;"wp-block-syntaxhighlighter-code ">&NewLine;<pre class&equals;"brush&colon; jscript&semi; title&colon; &semi; notranslate">&NewLine;import &lbrace; store &rcub; from '&commat;wordpress&sol;interactivity'&semi;&NewLine;&NewLine;store&lpar; 'myPlugin'&comma; &lbrace;&NewLine;&Tab;state&colon; &lbrace;&NewLine;&Tab;&Tab;get isOpen&lpar;&rpar; &lbrace;&NewLine;&Tab;&Tab;&Tab;const ctx &equals; getContext&lpar;&rpar;&semi;&NewLine;&Tab;&Tab;&Tab;return &excl;&excl; ctx&period;open&semi;&NewLine;&Tab;&Tab;&rcub;&comma;&NewLine;&Tab;&rcub;&comma;&NewLine;&rcub; &rpar;&semi;&NewLine;<&sol;pre>&NewLine;<&sol;div>&NewLine;<div class&equals;"wp-block-syntaxhighlighter-code ">&NewLine;<pre class&equals;"brush&colon; xml&semi; title&colon; &semi; notranslate">&NewLine;<div&NewLine;&Tab;data-wp-interactive&equals;"myPlugin"&NewLine;&Tab;data-wp-bind--hidden&equals;"&excl;state&period;isOpen"&NewLine;>&NewLine;&Tab;Content&period;&NewLine;<&sol;div>&NewLine;<&sol;pre>&NewLine;<&sol;div>&NewLine;<p>This <em>bad<&sol;em> &lpar;<imgsrc&equals;"" alt&equals;"❌" class&equals;"wp-smiley" style&equals;"height&colon; 1em&semi; max-height&colon; 1em&semi;">&rpar; example will&comma; going forward&comma; emit a deprecation warning&colon;<&sol;p>&NewLine;<div class&equals;"wp-block-syntaxhighlighter-code ">&NewLine;<pre class&equals;"brush&colon; jscript&semi; title&colon; &semi; notranslate">&NewLine;import &lbrace; store &rcub; from '&commat;wordpress&sol;interactivity'&semi;&NewLine;&NewLine;store&lpar; 'myPlugin'&comma; &lbrace;&NewLine;&Tab;actions&colon; &lbrace;&NewLine;&Tab;&Tab;isOpen&lpar;&rpar; &lbrace;&NewLine;&Tab;&Tab;&Tab;const ctx &equals; getContext&lpar;&rpar;&semi;&NewLine;&Tab;&Tab;&Tab;return &excl;&excl; ctx&period;open&semi;&NewLine;&Tab;&Tab;&rcub;&comma;&NewLine;&Tab;&rcub;&comma;&NewLine;&rcub; &rpar;&semi;&NewLine;<&sol;pre>&NewLine;<&sol;div>&NewLine;<div class&equals;"wp-block-syntaxhighlighter-code ">&NewLine;<pre class&equals;"brush&colon; xml&semi; title&colon; &semi; notranslate">&NewLine;<div&NewLine;&Tab;data-wp-interactive&equals;"myPlugin"&NewLine;&Tab;data-wp-bind--hidden&equals;"&excl;actions&period;isOpen"&NewLine;>&NewLine;&Tab;Content&period;&NewLine;<&sol;div>&NewLine;<&sol;pre>&NewLine;<&sol;div>&NewLine;<p>To provide context on why this new requirement is relevant&colon; Using store functions for anything other than the &OpenCurlyDoubleQuote;on”&comma; &OpenCurlyDoubleQuote;init”&comma; or &OpenCurlyDoubleQuote;watch” groups of directives has always been an anti-pattern&period; It is now being more formally discouraged&comma; and will in the future be made impossible&period;<&sol;p>&NewLine;<h2 class&equals;"wp-block-heading">Support for the <code>&period;length<&sol;code> property in directives<&sol;h2>&NewLine;<p>An additional Interactivity API enhancement in WordPress 6&period;8 is support for the <code>&period;length<&sol;code> property on strings and numeric arrays in directives&comma; ensuring consistency between server and client rendering&period;<&sol;p>&NewLine;<p>Previously&comma; the <code>&period;length<&sol;code> property was unavailable on the server&comma; requiring workarounds&period; This update allows developers to use <code>&period;length<&sol;code> within all directives that reference <a href&equals;"https&colon;&sol;&sol;developer&period;wordpress&period;org&sol;block-editor&sol;reference-guides&sol;interactivity-api&sol;core-concepts&sol;undestanding-global-state-local-context-and-derived-state&sol;">global state&comma; local context&comma; or derived state<&sol;a>&comma; aligning behavior across environments&period;<&sol;p>&NewLine;<p>This code example illustrates using the <code>&period;length<&sol;code> property&colon;<&sol;p>&NewLine;<div class&equals;"wp-block-syntaxhighlighter-code ">&NewLine;<pre class&equals;"brush&colon; jscript&semi; title&colon; &semi; notranslate">&NewLine;<div data-wp-interactive&equals;"example">&NewLine; <div data-wp-bind--hidden&equals;"&excl;state&period;list&period;length">&NewLine; <input type&equals;"range" min&equals;"1" data-wp-bind--max&equals;"state&period;list&period;length">&NewLine; <&sol;div>&NewLine; <div data-wp-bind--hidden&equals;"&excl;state&period;string&period;length">&NewLine; <h1 data-wp-text&equals;"state&period;string"><&sol;h1>&NewLine; <&sol;div>&NewLine;<&sol;div>&NewLine;<&sol;pre>&NewLine;<&sol;div>&NewLine;<p>This improvement streamlines logic and improves developer experience&period;<&sol;p>&NewLine;<h2 class&equals;"wp-block-heading">Summary and further reading<&sol;h2>&NewLine;<p>Please refer to the following links for further reading&colon;<&sol;p>&NewLine;<ul class&equals;"wp-block-list">&NewLine;<li>Gutenberg pull request <a href&equals;"https&colon;&sol;&sol;github&period;com&sol;WordPress&sol;gutenberg&sol;pull&sol;68097">&num;68097<&sol;a> for the <code>withSyncEvent<&sol;code> and new directive requirement enhancements<&sol;li>&NewLine;<li>Gutenberg issues <a href&equals;"https&colon;&sol;&sol;github&period;com&sol;WordPress&sol;gutenberg&sol;issues&sol;64944">&num;64944<&sol;a> and <a href&equals;"https&colon;&sol;&sol;github&period;com&sol;WordPress&sol;gutenberg&sol;issues&sol;69552">&num;69552<&sol;a> with additional context on the long-term plans to run Interactivity API actions asynchronously by default&period;<&sol;li>&NewLine;<li>Gutenberg issue <a href&equals;"https&colon;&sol;&sol;github&period;com&sol;WordPress&sol;gutenberg&sol;issues&sol;69269">&num;69269<&sol;a> with additional context on the long-term plans to more clearly separate directives that <em>do<&sol;em> something vs that determine a <em>value<&sol;em>&period;<&sol;li>&NewLine;<li>Trac ticket <a href&equals;"https&colon;&sol;&sol;core&period;trac&period;wordpress&period;org&sol;ticket&sol;62582">&num;62582<&sol;a> for support of the <code>&period;length<&sol;code> property&period;<&sol;li>&NewLine;<li>Documentation for understanding <a href&equals;"https&colon;&sol;&sol;developer&period;wordpress&period;org&sol;block-editor&sol;reference-guides&sol;interactivity-api&sol;core-concepts&sol;undestanding-global-state-local-context-and-derived-state&sol;">global state&comma; local context&comma; or derived state<&sol;a>&period;<&sol;li>&NewLine;<&sol;ul>&NewLine;<p class&equals;"has-text-align-right"><em>Co-authored by <a href&equals;"https&colon;&sol;&sol;profiles&period;wordpress&period;org&sol;gziolo&sol;" class&equals;"mention"><span class&equals;"mentions-prefix">&commat;<&sol;span>gziolo<&sol;a>&period;<&sol;em><br &sol;><em>Props to <a href&equals;"https&colon;&sol;&sol;profiles&period;wordpress&period;org&sol;westonruter&sol;" class&equals;"mention"><span class&equals;"mentions-prefix">&commat;<&sol;span>westonruter<&sol;a>&comma; <a href&equals;"https&colon;&sol;&sol;profiles&period;wordpress&period;org&sol;jonsurrell&sol;" class&equals;"mention"><span class&equals;"mentions-prefix">&commat;<&sol;span>jonsurrell<&sol;a>&comma; <a href&equals;"https&colon;&sol;&sol;profiles&period;wordpress&period;org&sol;webcommsat&sol;" class&equals;"mention"><span class&equals;"mentions-prefix">&commat;<&sol;span>webcommsat<&sol;a>&comma; <a href&equals;"https&colon;&sol;&sol;profiles&period;wordpress&period;org&sol;marybaum&sol;" class&equals;"mention"><span class&equals;"mentions-prefix">&commat;<&sol;span>marybaum<&sol;a> for review and proofreading&period;<&sol;em><&sol;p>&NewLine;<p class&equals;"o2-appended-tags"><a href&equals;"https&colon;&sol;&sol;make&period;wordpress&period;org&sol;core&sol;tag&sol;6-8&sol;" class&equals;"tag"><span class&equals;"tag-prefix">&num;<&sol;span>6-8<&sol;a>&comma; <a href&equals;"https&colon;&sol;&sol;make&period;wordpress&period;org&sol;core&sol;tag&sol;dev-notes&sol;" class&equals;"tag"><span class&equals;"tag-prefix">&num;<&sol;span>dev-notes<&sol;a>&comma; <a href&equals;"https&colon;&sol;&sol;make&period;wordpress&period;org&sol;core&sol;tag&sol;dev-notes-6-8&sol;" class&equals;"tag"><span class&equals;"tag-prefix">&num;<&sol;span>dev-notes-6-8<&sol;a>&comma; <a href&equals;"https&colon;&sol;&sol;make&period;wordpress&period;org&sol;core&sol;tag&sol;interactivity-api&sol;" class&equals;"tag"><span class&equals;"tag-prefix">&num;<&sol;span>interactivity-api<&sol;a>&comma; <a href&equals;"https&colon;&sol;&sol;make&period;wordpress&period;org&sol;core&sol;tag&sol;performance&sol;" class&equals;"tag"><span class&equals;"tag-prefix">&num;<&sol;span>performance<&sol;a><&sol;p>&NewLine;<&sol;div>&NewLine;

Sponsored
Sponsored
A WordPress Commenter

Recent Posts

Cloudways Brings Back Prepathon Next Week With Focus on Gen Z and Gen Alpha

Cloudways is bringing back its free Prepathon online event next week, from September 30 to…

3 days ago

Fueled Layoffs Spark Tension After Former Employee Pre-Empts Announcement

Fueled has confirmed layoffs this week, cutting 4–5% of its workforce. But the news reached…

3 days ago

Nick Hamze’s ‘Cool Kids’ Post Kicks Off Fresh Debate on WordPress’s Image Problem

After calling for “more weirdness” in WordPress theme design earlier this year, Nick Hamze has…

4 days ago

New FAIR 1.0 Release Brings Decentralized Package Management to WordPress

FAIR has reached its first major milestone with the release of version 1.0 this week,…

4 days ago

Performance Chat Summary: 23 September 2025

The full chat log is available beginning here on Slack. WordPress Performance Trac tickets @westonruter…

5 days ago

From RV Life to CEO: Jon Penland’s Unlikely Road to Leading Kinsta

Back in 2011, Jon Penland was selling centrifugal pumping units into the water and wastewater…

6 days ago