Repository navigation
Interactivity Router: provide a way to preserve elements across client-side navigation (successor to data-wp-ignore) #80298
Description
This is a feature request and discussion starter, not a bug report.
The gap
data-wp-ignore is deprecated with no replacement:
// data-wp-ignore (deprecated)
directive(
'ignore',
( { ... } ) => {
if ( globalThis.SCRIPT_DEBUG ) {
warn(
'The data-wp-ignore directive is deprecated and will be removed in version 7.0.'
);
}
...(packages/interactivity/src/directives.tsx, around lines 810 to 834)
On the deprecation issue, #70881, @sirreal asked:
Are there alternatives to the ignore directive? I saw the deprecation message recently, but it's unclear whether I can do anything about it or where to go for more information.
And @emeaguiar followed up with a concrete case:
A third part script was adding an
onClickto the markup on one site, this triggered an error in the interactivity api anddata-wp-ignorefixes it, is there a way to get around this now?
Neither got a real answer with a working alternative.
The underlying problem is bigger than data-wp-ignore itself. Scripts that aren't built on the Interactivity API, consent managers like OneTrust, chat widgets, various embeds, inject DOM at runtime. The router's vDOM diffing doesn't know about that DOM, and either removes it or clobbers it on the next navigation. The docs already say as much:
Elements added this way (like dynamically created tooltips or injected widgets) will vanish after navigating away and back, because the virtual DOM diffing is not aware of them.
(docs/reference-guides/interactivity-api/core-concepts/client-side-navigation-compatibility.md, line 266)
Under the experimental full-page client-side navigation, the entire <body> is treated as a single router region, so there's no longer a safe spot outside a region to inject anything into either.
A related, stalled issue is #63249, which asks whether a router region should be removed when it isn't present on the new page. Same underlying need: some content should just be left alone by the diffing algorithm.
Prior art
Other client-side routers already solve this. Turbo has data-turbo-permanent, which keeps an element (matched by id) intact across page swaps. htmx has hx-preserve for the same purpose. Both exist specifically for things like chat widgets, embedded players, and consent banners, the same category of third-party DOM the Interactivity API router struggles with today.
Proposal to discuss
An opt-in directive, something like data-wp-preserve, matched by id, that tells the router to keep the existing live element as is instead of diffing or removing it.
The important part: this needs to be something the site owner can add to a wrapper element they control, since the third-party script itself will never add a WordPress-specific attribute to the markup it injects. So the directive would go on a container the theme or block renders, not on the vendor's own DOM.
This would pair well with the head-asset persistence work in #76031 and with a navigation lifecycle event, something like #70882 already touched on for a 7.1 replacement to the internal navigation state. Between the three, third-party scripts would have a way to detect a navigation, survive it without losing their DOM, and re-run their own setup afterward.
Curious to hear if this has been discussed before, or if there's a reason data-wp-ignore was removed outright instead of replaced.
Activity