Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment: Add full page client-side navigation experiment setting #59707

Merged
merged 61 commits into from
Apr 22, 2024

Conversation

SantosGuillamot
Copy link
Contributor

@SantosGuillamot SantosGuillamot commented Mar 8, 2024

What?

This pull request adds an experiment in Gutenberg -> Experiments to enable full page client-side navigation in your site using the Interactivity API.

It enables the user experience showcased in the State Of The Word and in reflected in the Movies demo.

State Of The Word 2023

Client-side navigation refers to the process of navigating between different pages without the need for a full page refresh. The Interactivity API takes care of fetching the new content from the server and replacing the relevant parts in the DOM, while maintaining the UI state. This approach provides a SPA experience, which is smoother and opens up new possibilities.

One of the limitations of this approach is that all the scripts must be compatible with the Interactivity API, and that's why it can only be enabled in controlled environments until the API is a bit more mature. Additionally, we need to explore deeper how to handle new scripts and styles.

We can differentiate between two types of client-side navigation:

Region based client-side navigation (existing router implementation)

This type of navigation was included as a first step and it just replaces specific regions of the DOM. This is safer because just the selected regions must be compatible with the Interactivity API. This is used, for example, to enhance the pagination of the Query Loop block.

Full page client-side navigation (enabled by this experiment)

This type of navigation does replace the whole DOM and not just specific regions. As mentioned above, there might be incompatibilities with other scripts, so it should only be used in controlled environments. This experiment should help to clarify what is needed and how it could be implemented.

Why?

The idea is to include it as experimental to start testing it and explore what needs to be done to offer it as a site option without the experimental flag.

How?

There are a few changes in this pull request:

  • It adds a new setting in the experiments panel: link. When that option is enabled, it loads conditionally the relevant PHP code.
  • If the experiment is enabled, it adds data-wp-interactive to all the root blocks: link.
  • If the experiment is enabled, it registers a new interactivity config setting that can be read in PHP or in JS: link.
  • It creates a new interactivity-router module named full-csn to handle the whole site and not only regions: link. It is based on the one there was in the initial experiments: link.
  • If the experiment is enabled, it registers the new router and, if not, it loads the old one like it is doing in trunk: link.
  • If the experiment is enabled, it adds some directives to all links to prefetch the new page and navigate on click using the router: link. This should probably not be done by Gutenberg but each site owner should decide where to use it. It is useful now for testing.
  • It adapts the query loop block to the new router and loads the script always when the experiment is enabled.

Testing Instructions

  1. Enable the experiment in Gutenberg -> Experiments.
  2. Click on links in your site and check that the page is not refreshed.
@SantosGuillamot SantosGuillamot added [Type] Experimental Experimental feature or API. [Feature] Interactivity API API to add frontend interactivity to blocks. labels Mar 8, 2024
Copy link

github-actions bot commented Mar 8, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: SantosGuillamot <santosguillamot@git.wordpress.org>
Co-authored-by: cbravobernal <cbravobernal@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>
Co-authored-by: DAreRodz <darerodz@git.wordpress.org>
Co-authored-by: luisherranz <luisherranz@git.wordpress.org>
Co-authored-by: michalczaplinski <czapla@git.wordpress.org>
Co-authored-by: felixarntz <flixos90@git.wordpress.org>
Co-authored-by: westonruter <westonruter@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link

github-actions bot commented Mar 8, 2024

This pull request changed or added PHP files in previous commits, but none have been detected in the latest commit.

Thank you! ❤️

Copy link

github-actions bot commented Mar 8, 2024

Size Change: +22.6 kB (+1%)

Total Size: 1.75 MB

Filename Size Change
build/annotations/index.min.js 2.27 kB -424 B (-16%) 👏
build/block-directory/index.min.js 7.26 kB +36 B (0%)
build/block-directory/style-rtl.css 1.03 kB +1 B (0%)
build/block-directory/style.css 1.03 kB +1 B (0%)
build/block-editor/content-rtl.css 4.5 kB +95 B (+2%)
build/block-editor/content.css 4.5 kB +99 B (+2%)
build/block-editor/default-editor-styles-rtl.css 395 B +1 B (0%)
build/block-editor/default-editor-styles.css 395 B +1 B (0%)
build/block-editor/index.min.js 256 kB +3.44 kB (+1%)
build/block-editor/style-rtl.css 15.6 kB -87 B (-1%)
build/block-editor/style.css 15.6 kB -96 B (-1%)
build/block-library/blocks/audio/theme-rtl.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/audio/theme.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/cover/editor-rtl.css 671 B +24 B (+4%)
build/block-library/blocks/cover/editor.css 674 B +24 B (+4%)
build/block-library/blocks/cover/style-rtl.css 1.7 kB +7 B (0%)
build/block-library/blocks/cover/style.css 1.69 kB +7 B (0%)
build/block-library/blocks/details/style-rtl.css 86 B -12 B (-12%) 👏
build/block-library/blocks/details/style.css 86 B -12 B (-12%) 👏
build/block-library/blocks/embed/theme-rtl.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/embed/theme.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/file/editor-rtl.css 326 B +10 B (+3%)
build/block-library/blocks/file/editor.css 327 B +11 B (+3%)
build/block-library/blocks/image/editor-rtl.css 878 B -16 B (-2%)
build/block-library/blocks/image/editor.css 878 B -15 B (-2%)
build/block-library/blocks/image/theme-rtl.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/image/theme.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/media-text/editor-rtl.css 306 B +40 B (+15%) ⚠️
build/block-library/blocks/media-text/editor.css 305 B +42 B (+16%) ⚠️
build/block-library/blocks/navigation/view.min.js 1.03 kB +14 B (+1%)
build/block-library/blocks/post-featured-image/editor-rtl.css 729 B +63 B (+9%) 🔍
build/block-library/blocks/post-featured-image/editor.css 727 B +65 B (+10%) ⚠️
build/block-library/blocks/pullquote/style.css 353 B -1 B (0%)
build/block-library/blocks/pullquote/theme-rtl.css 174 B +6 B (+4%)
build/block-library/blocks/pullquote/theme.css 174 B +6 B (+4%)
build/block-library/blocks/quote/theme-rtl.css 233 B +10 B (+4%)
build/block-library/blocks/quote/theme.css 235 B +9 B (+4%)
build/block-library/blocks/search/style-rtl.css 690 B +61 B (+10%) ⚠️
build/block-library/blocks/search/style.css 689 B +61 B (+10%) ⚠️
build/block-library/blocks/separator/style-rtl.css 239 B +10 B (+4%)
build/block-library/blocks/separator/style.css 239 B +10 B (+4%)
build/block-library/blocks/site-logo/editor-rtl.css 801 B +47 B (+6%) 🔍
build/block-library/blocks/site-logo/editor.css 801 B +47 B (+6%) 🔍
build/block-library/blocks/social-links/editor-rtl.css 676 B -6 B (-1%)
build/block-library/blocks/social-links/editor.css 675 B -6 B (-1%)
build/block-library/blocks/table/theme-rtl.css 152 B +6 B (+4%)
build/block-library/blocks/table/theme.css 152 B +6 B (+4%)
build/block-library/blocks/template-part/editor-rtl.css 431 B +28 B (+7%) 🔍
build/block-library/blocks/template-part/editor.css 431 B +28 B (+7%) 🔍
build/block-library/blocks/template-part/theme-rtl.css 107 B +6 B (+6%) 🔍
build/block-library/blocks/template-part/theme.css 107 B +6 B (+6%) 🔍
build/block-library/blocks/video/theme-rtl.css 133 B +7 B (+6%) 🔍
build/block-library/blocks/video/theme.css 133 B +7 B (+6%) 🔍
build/block-library/common-rtl.css 1.11 kB +1 B (0%)
build/block-library/common.css 1.11 kB +1 B (0%)
build/block-library/editor-rtl.css 12.4 kB +45 B (0%)
build/block-library/editor.css 12.4 kB +46 B (0%)
build/block-library/index.min.js 218 kB +1.51 kB (+1%)
build/block-library/style-rtl.css 14.8 kB +33 B (0%)
build/block-library/style.css 14.8 kB +30 B (0%)
build/block-library/theme-rtl.css 707 B +19 B (+3%)
build/block-library/theme.css 713 B +20 B (+3%)
build/blocks/index.min.js 51.6 kB -229 B (0%)
build/commands/index.min.js 15.2 kB -405 B (-3%)
build/commands/style-rtl.css 953 B +18 B (+2%)
build/commands/style.css 951 B +21 B (+2%)
build/components/index.min.js 222 kB -1.2 kB (-1%)
build/components/style-rtl.css 11.9 kB +58 B (0%)
build/components/style.css 11.9 kB +62 B (+1%)
build/core-data/index.min.js 72.5 kB -264 B (0%)
build/customize-widgets/index.min.js 11.2 kB +26 B (0%)
build/customize-widgets/style-rtl.css 1.36 kB +2 B (0%)
build/customize-widgets/style.css 1.36 kB +1 B (0%)
build/data/index.min.js 9 kB +56 B (+1%)
build/edit-post/classic-rtl.css 579 B +21 B (+4%)
build/edit-post/classic.css 579 B +21 B (+4%)
build/edit-post/index.min.js 19.7 kB -4.44 kB (-18%) 👏
build/edit-post/style-rtl.css 4.44 kB -1.13 kB (-20%) 🎉
build/edit-post/style.css 4.44 kB -1.13 kB (-20%) 🎉
build/edit-site/index.min.js 227 kB +10.6 kB (+5%) 🔍
build/edit-site/style-rtl.css 14.1 kB -927 B (-6%)
build/edit-site/style.css 14.1 kB -935 B (-6%)
build/edit-widgets/index.min.js 17.7 kB +429 B (+2%)
build/edit-widgets/style-rtl.css 4.16 kB -9 B (0%)
build/edit-widgets/style.css 4.16 kB -4 B (0%)
build/editor/index.min.js 76.1 kB +12.4 kB (+19%) ⚠️
build/editor/style-rtl.css 6.74 kB +1.4 kB (+26%) 🚨
build/editor/style.css 6.74 kB +1.41 kB (+26%) 🚨
build/format-library/index.min.js 8.07 kB +179 B (+2%)
build/format-library/style-rtl.css 493 B +1 B (0%)
build/format-library/style.css 492 B +2 B (0%)
build/interactivity/index.min.js 13 kB +66 B (+1%)
build/interactivity/navigation.min.js 1.17 kB +17 B (+1%)
build/interactivity/router.min.js 2.79 kB +1.43 kB (+105%) 🆘
build/keyboard-shortcuts/index.min.js 1.3 kB -438 B (-25%) 🎉
build/list-reusable-blocks/style.css 851 B +2 B (0%)
build/media-utils/index.min.js 2.92 kB +20 B (+1%)
build/nux/index.min.js 1.57 kB -429 B (-22%) 🎉
build/nux/style-rtl.css 748 B +1 B (0%)
build/nux/style.css 744 B +2 B (0%)
build/patterns/index.min.js 6.38 kB +707 B (+12%) ⚠️
build/patterns/style-rtl.css 595 B +42 B (+8%) 🔍
build/patterns/style.css 595 B +43 B (+8%) 🔍
build/preferences-persistence/index.min.js 2.06 kB +6 B (0%)
build/preferences/index.min.js 2.83 kB +5 B (0%)
build/reusable-blocks/index.min.js 2.73 kB +5 B (0%)
build/rich-text/index.min.js 10 kB -328 B (-3%)
build/router/index.min.js 1.88 kB +90 B (+5%) 🔍
build/server-side-render/index.min.js 1.96 kB +4 B (0%)
build/style-engine/index.min.js 2.03 kB -68 B (-3%)
build/url/index.min.js 3.74 kB +14 B (0%)
build/vendors/react-dom.min.js 41.7 kB -52 B (0%)
build/widgets/index.min.js 7.23 kB +22 B (0%)
build/widgets/style-rtl.css 1.17 kB +1 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 955 B
build/api-fetch/index.min.js 2.32 kB
build/autop/index.min.js 2.1 kB
build/blob/index.min.js 578 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/button/editor-rtl.css 415 B
build/block-library/blocks/button/editor.css 414 B
build/block-library/blocks/button/style-rtl.css 627 B
build/block-library/blocks/button/style.css 626 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 113 B
build/block-library/blocks/categories/editor.css 112 B
build/block-library/blocks/categories/style-rtl.css 124 B
build/block-library/blocks/categories/style.css 124 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 421 B
build/block-library/blocks/columns/style.css 421 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/embed/editor-rtl.css 322 B
build/block-library/blocks/embed/editor.css 322 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/file/style-rtl.css 280 B
build/block-library/blocks/file/style.css 281 B
build/block-library/blocks/file/view.min.js 324 B
build/block-library/blocks/footnotes/style-rtl.css 201 B
build/block-library/blocks/footnotes/style.css 199 B
build/block-library/blocks/form-input/editor-rtl.css 227 B
build/block-library/blocks/form-input/editor.css 227 B
build/block-library/blocks/form-input/style-rtl.css 343 B
build/block-library/blocks/form-input/style.css 343 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 340 B
build/block-library/blocks/form-submission-notification/editor.css 340 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/form/view.min.js 471 B
build/block-library/blocks/freeform/editor-rtl.css 2.61 kB
build/block-library/blocks/freeform/editor.css 2.61 kB
build/block-library/blocks/gallery/editor-rtl.css 947 B
build/block-library/blocks/gallery/editor.css 952 B
build/block-library/blocks/gallery/style-rtl.css 1.72 kB
build/block-library/blocks/gallery/style.css 1.72 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 647 B
build/block-library/blocks/group/editor.css 647 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 189 B
build/block-library/blocks/heading/style.css 189 B
build/block-library/blocks/html/editor-rtl.css 336 B
build/block-library/blocks/html/editor.css 337 B
build/block-library/blocks/image/style-rtl.css 1.6 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/view.min.js 1.54 kB
build/block-library/blocks/latest-comments/style-rtl.css 357 B
build/block-library/blocks/latest-comments/style.css 357 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/style-rtl.css 505 B
build/block-library/blocks/media-text/style.css 503 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 668 B
build/block-library/blocks/navigation-link/editor.css 669 B
build/block-library/blocks/navigation-link/style-rtl.css 259 B
build/block-library/blocks/navigation-link/style.css 257 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 296 B
build/block-library/blocks/navigation-submenu/editor.css 295 B
build/block-library/blocks/navigation/editor-rtl.css 2.26 kB
build/block-library/blocks/navigation/editor.css 2.26 kB
build/block-library/blocks/navigation/style-rtl.css 2.26 kB
build/block-library/blocks/navigation/style.css 2.25 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 377 B
build/block-library/blocks/page-list/editor.css 377 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 235 B
build/block-library/blocks/paragraph/editor.css 235 B
build/block-library/blocks/paragraph/style-rtl.css 335 B
build/block-library/blocks/paragraph/style.css 335 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 508 B
build/block-library/blocks/post-comments-form/style.css 508 B
build/block-library/blocks/post-content/editor-rtl.css 74 B
build/block-library/blocks/post-content/editor.css 74 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 141 B
build/block-library/blocks/post-excerpt/style.css 141 B
build/block-library/blocks/post-featured-image/style-rtl.css 342 B
build/block-library/blocks/post-featured-image/style.css 342 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 409 B
build/block-library/blocks/post-template/style.css 408 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 69 B
build/block-library/blocks/post-time-to-read/style.css 69 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 354 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 486 B
build/block-library/blocks/query/editor.css 486 B
build/block-library/blocks/query/view.min.js 958 B
build/block-library/blocks/quote/style-rtl.css 237 B
build/block-library/blocks/quote/style.css 237 B
build/block-library/blocks/read-more/style-rtl.css 140 B
build/block-library/blocks/read-more/style.css 140 B
build/block-library/blocks/rss/editor-rtl.css 149 B
build/block-library/blocks/rss/editor.css 149 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 184 B
build/block-library/blocks/search/editor.css 184 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/search/view.min.js 478 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 323 B
build/block-library/blocks/shortcode/editor.css 323 B
build/block-library/blocks/site-logo/style-rtl.css 204 B
build/block-library/blocks/site-logo/style.css 204 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/style-rtl.css 1.48 kB
build/block-library/blocks/social-links/style.css 1.48 kB
build/block-library/blocks/spacer/editor-rtl.css 350 B
build/block-library/blocks/spacer/editor.css 350 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 395 B
build/block-library/blocks/table/editor.css 395 B
build/block-library/blocks/table/style-rtl.css 639 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/term-description/style-rtl.css 111 B
build/block-library/blocks/term-description/style.css 111 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/blocks/video/style-rtl.css 185 B
build/block-library/blocks/video/style.css 185 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/compose/index.min.js 12.6 kB
build/core-commands/index.min.js 2.77 kB
build/data-controls/index.min.js 640 B
build/date/index.min.js 17.9 kB
build/deprecated/index.min.js 451 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.65 kB
build/element/index.min.js 4.83 kB
build/escape-html/index.min.js 537 B
build/hooks/index.min.js 1.55 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.58 kB
build/interactivity/debug.min.js 16.2 kB
build/interactivity/file.min.js 447 B
build/interactivity/image.min.js 1.67 kB
build/interactivity/query.min.js 740 B
build/interactivity/search.min.js 618 B
build/is-shallow-equal/index.min.js 527 B
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.11 kB
build/list-reusable-blocks/style-rtl.css 851 B
build/modules/importmap-polyfill.min.js 12.2 kB
build/notices/index.min.js 948 B
build/plugins/index.min.js 1.8 kB
build/preferences/style-rtl.css 710 B
build/preferences/style.css 712 B
build/primitives/index.min.js 975 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 1 kB
build/react-i18n/index.min.js 623 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.78 kB
build/redux-routine/index.min.js 2.7 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/shortcode/index.min.js 1.39 kB
build/token-list/index.min.js 582 B
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 957 B
build/warning/index.min.js 249 B
build/widgets/style.css 1.17 kB
build/wordcount/index.min.js 1.02 kB

compressed-size-action

Comment on lines 155 to 160
const isValidLink = ( ref ) =>
ref &&
ref instanceof window.HTMLAnchorElement &&
ref.href &&
( ! ref.target || ref.target === '_self' ) &&
ref.origin === window.location.origin;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@felixarntz felixarntz Apr 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also wp-login.php. See similar Speculative Loading plugin exclusions.

In fact, we're even providing a filter (though that could be added later here).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also important to check for whether the link is for an anchor link for another part of the page: https://github.com/WordPress/wordpress-develop/blob/f525e665b6ea6e88289d82cad5fc1dfac57db109/src/js/_enqueues/wp/customize/preview.js#L156-L160

So this here should also check if ! ref.getAttribute('href').startsWith('#').

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback and the links! I added the checks for wp-admin, wp-login, _wpnonce, and anchors as part of this conditional. Let me know if that's not what you had in mind.

Co-authored-by: Michal <mmczaplinski@gmail.com>
@SantosGuillamot
Copy link
Contributor Author

SantosGuillamot commented Apr 16, 2024

Thanks a lot for all the feedback. I've been reviewing all the remaining comments and I believe this is how I will proceed:

To do in this pull request

  • Use event delegation on the client instead of using data-wp-on--click directive in every link: link.
  • Previous task will allow us to use just one navigate function with the existing format, using url as the parameter: link.
  • Use a static variable to add the <body> tag once: link. And potentially use a closing tag.
  • Exclude wp-admin and wp-login from links and ensure anchors work as expected: link.
  • Wrap fetch in a try/catch (the whole conditional): link.
  • Add experimental message in the help attribute: link.
  • Rename document parameter: link.
  • Wrap the fullPage navigation mode in IS_GUTENBERG_PLUGIN check: link.

To improve after that

  • Accept only a string in the url parameter and adapt the tests to reflect that: link.
  • Explore deeper how to use event delegation in the client: link.
  • Add e2e tests: link.
  • Explore how to update query attribute when the experiment is enabled: link. It looks like a core bug.
  • Revisit how to fetch head assets: link.
  • Explore how to modify the body tag without the hack: link.
  • Explore how this interacts with Speculation Rules API: link.
  • Explore if we want to add event listeners to mobile: link. (Maybe on click is enough)
Copy link

Flaky tests detected in 745e675.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/8719955449
📝 Reported issues:

@SantosGuillamot
Copy link
Contributor Author

I believe this experiment is ready to be merged. I addressed all the feedback listed here. We should probably create a tracking issue for client-side navigation and add the follow-up tasks there, and potentially create specific issues for some of them.

Comment on lines +164 to +165
! ref.pathname.startsWith( '/wp-admin' ) &&
! ref.pathname.startsWith( '/wp-login.php' ) &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes WordPress sites install core in a subdirectory, like /wp/. In such cases home_url() and site_url() are different, e.g. http://example.com/ vs https://example.com/wp/.

Additionally, in multisite subdirectory installs, there will also be path segment(s) before /wp-admin.

Easiest way to handle that right now is to just check if the path includes the strings:

Suggested change
! ref.pathname.startsWith( '/wp-admin' ) &&
! ref.pathname.startsWith( '/wp-login.php' ) &&
! ref.pathname.includes( '/wp-admin' ) &&
! ref.pathname.includes( '/wp-login.php' ) &&

This is not as robust as possible. But better to err on the side of not doing client-side navigation than doing it with an invalid target.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m simply reading the discussion, but seeing this solution would not work for my sites, because for security I always change the default wp-admin url. Maybe check for a class name or other attribute in the dom instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, these paths should be passed from PHP so they don't have to be hard coded in JS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Maybe we can use wp_interactivity_config to create a new isAdmin property that is passed to the client reading is_admin in PHP.

cc: @DAreRodz Worth adding this to the tracking issue as a follow-up task?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it would be is_admin() since this would always just be false in the frontend context. I think we'd need to instead get an array of the special paths, including get_admin_url(), wp_login_url(), etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added this as a task on the tracking issue.

);
// Prefetch on hover.
document.addEventListener(
'mouseenter',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On touch interfaces, I understand that the mouseenter event does fire but after a 300 ms delay. To ensure that prefetch happens immediately on a touch device, I suggest adding the same handler for the touchstart event. Or apparently pointerenter will handle both of these and it is supported by all browsers: https://caniuse.com/mdn-api_element_pointerenter_event

// Once this code is tested and more mature, the head should be updated for region based navigation as well.
if ( process.env.IS_GUTENBERG_PLUGIN ) {
if ( navigationMode === 'fullPage' ) {
// Cache the scripts. Has to be called before fetching the assets.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the caching required? Is this to guarantee execution order of the scripts when the page is loaded? What if a script is not cacheable?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or is this rather to ensure that there is no flash of unrendered content?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that the original idea was simply that when doing a full-page navigation to another page, we don't want to re-download the scripts that were already present on the initial page.

If a script is not cacheable (e.g. if some of the script's contents are generated dynamically) that's indeed currently a problem.

One solution could be examine the HTTP headers and e.g. skip the ones with Cache-Control: no-store , Cache-Control: no-cache or Expires: <Date in the past>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @michalczaplinski, for chiming in. 😄

We want to revisit the whole assets system, and examining HTTP headers is something we could try.

BTW, I've created a tracking issue to continue with the development. #60951

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Indeed, we should take a holistic view of this. Thanks for creating the issue! 🙏

@DAreRodz DAreRodz merged commit e16ea9f into trunk Apr 22, 2024
78 of 81 checks passed
@DAreRodz DAreRodz deleted the experiment/add-full-client-side-navigation branch April 22, 2024 11:38
@github-actions github-actions bot added this to the Gutenberg 18.3 milestone Apr 22, 2024
@DAreRodz
Copy link
Contributor

Thanks everyone for your work and feedback. 🙌

I've created this tracking issue to keep track of the progress and continue working on this feature. The list of tasks is based on all the feedback gathered from this PR.

@luisherranz
Copy link
Member

I'm a little concerned about fetching scripts in fetchHeadAssets() without taking into account the script order.

@michalczaplinski We shouldn't really load unknown scripts. We just did it to get it working with the WP movies demo.

We should only load the module scripts that belong to the new blocks on the page or other module scripts that have declared their compatibility with full-page client-side navigation.

@luisherranz
Copy link
Member

I arrive a bit late to the party, but I simply want to say incredible work here. Thanks to Mario for leading this and to the rest for all the valuable feedback.This is very exciting!! 👏😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Interactivity API API to add frontend interactivity to blocks. [Type] Experimental Experimental feature or API.
9 participants