Interactivity Router
๐ **Source:** [Interactivity Router](https://www.youtube.com/watch?v=hlbT0fnIe8E)
> [!note]+ Document Notes
> tags: [interactivity-api, wordpress, javascript, router]
> author: Juanma Garrido
> source: YouTube
> reference: https://www.youtube.com/watch?v=hlbT0fnIe8E
> date created: 2024-12-19 10:30
>
> # ๐ท๏ธ Title: Interactivity Router - Client-Side Navigation for WordPress
>
<!-- deep-read:sections start -->
## ๐งฐ Action Inbox
- [H1] Enable client-side navigation in Query Loop blocks โ 6.9 feature #wordpress
- [H2] Implement router regions with data-wp-router-region attribute โ performance optimization #development
- [H3] Use script modules instead of bundled JS for better performance โ experimental-modules flag #optimization
## ๐งญ Table of Contents
- [๐ Summary](#-summary)
- [๐ Main Content](#-main-content)
- [๐๏ธ Notes](#๏ธ-notes)
- [๐ References](#-references)
- [๐ฃ๏ธ Paraphrase](#๏ธ-paraphrase)
- [๐ฐ Newsletter](#-newsletter)
- [โ
Action Items](#-action-items)
- [๐งช Hypotheses](#-hypotheses)
- [๐ Methodology](#-methodology)
- [โ Questions](#-questions)
- [๐ฎ Future Research](#-future-research)
- [๐ก Implications](#-implications)
- [๐ง Learning Styles Assessment](#-learning-styles-assessment)
- [๐ Accessibility Assessment](#-accessibility-assessment)
- [๐ DEIB Assessment](#-deib-assessment)
- [โ
Logical Validity](#-logical-validity)
- [๐ก๏ธ DARVO Analysis](#-darvo-analysis)
- [๐ฏ Conclusion](#-conclusion)
### ๐ References
- [WordPress Interactivity API Documentation](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/)
- [Block Development Examples](https://github.com/WordPress/block-development-examples)
## ๐ Summary
- WordPress 6.9 introduces client-side navigation through the Interactivity Router
- Query Loop blocks can now navigate without full page reloads using router regions
- Only specific DOM portions are updated, dramatically improving performance
- The system works similar to React's single-page application model
- Developers can build interactive blocks that maintain state across navigation
## ๐ Main Content
The Interactivity Router is a package within WordPress's Interactivity API that enables client-side navigation, transforming WordPress sites into single-page application experiences. This system fetches page HTML in the background and updates only specific DOM regions marked with `data-wp-router-region`, avoiding full page reloads.
The router leverages JavaScript modules for performance optimization. Instead of bundling all dependencies, it serves lightweight modules that import the Interactivity API engine dynamically. This approach reduces bundle size and enables better caching strategies.
State management works across both server and client contexts. The system merges server-provided initial state with client-defined state, allowing blocks to maintain data across navigation while receiving page-specific updates through a soft-merge process.
## ๐๏ธ Notes
#### โฑ๏ธ [00:00](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=0) โ [H1] Introduction to Interactivity Router
- Key idea: Router enables client-side navigation in WordPress blocks
- Evidence: "Query loop block by default triggers full reload but can be set to client side navigation"
#### โฑ๏ธ [02:30](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=150) โ [H2] WordPress 6.9 Router Toggle
- Key idea: Client-side navigation toggle now available in Query Loop advanced settings
- Evidence: "This toggle was disabled because modules weren't loaded properly, fixed in 6.9"
#### โฑ๏ธ [05:15](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=315) โ [H3] Performance Benefits Demonstration
- Key idea: Router navigation shows no new document requests in network tab
- Evidence: "No full page reload anymore, fetching HTML via background requests only"
#### โฑ๏ธ [08:45](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=525) โ [H2] Interactive Blocks Within Router Regions
- Key idea: Blocks maintain interactivity during client-side navigation
- Evidence: "Lightbox behavior works within router regions using data-wp directives"
#### โฑ๏ธ [12:00](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=720) โ [H1] Router Region Definition
- Key idea: data-wp-router-region attribute defines updateable areas
- Evidence: "Only portions marked as router regions get updated during navigation"
#### โฑ๏ธ [15:30](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=930) โ [H3] Documentation and Examples
- Key idea: Comprehensive examples available in WordPress developer resources
- Evidence: "Block development examples repo has interactivity API examples with live demos"
#### โฑ๏ธ [18:20](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=1100) โ [H2] Quiz Application Example
- Key idea: Complex interactive applications possible with router navigation
- Evidence: "Quiz with timed questions maintains state across page navigation"
#### โฑ๏ธ [22:00](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=1320) โ [H1] Script Modules vs Bundled JavaScript
- Key idea: Script modules reduce bundle size and improve performance
- Evidence: "Using view-script-module instead of view-script prevents library bundling"
#### โฑ๏ธ [25:40](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=1540) โ [H2] Dynamic Module Loading
- Key idea: Router package loads only when navigation occurs
- Evidence: "actions.navigate dynamically imports interactivity router on first use"
#### โฑ๏ธ [28:15](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=1695) โ [H3] State vs Context Usage Guidelines
- Key idea: Use context for DOM-specific data, state for cross-block communication
- Evidence: "Local context affects specific DOM portions, global state enables block communication"
#### โฑ๏ธ [32:00](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=1920) โ [H2] Server-Client State Merging
- Key idea: Soft merge preserves client state while adding server updates
- Evidence: "New properties added automatically, existing values require manual handling"
#### โฑ๏ธ [35:30](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=2130) โ [H3] Custom Template Implementation
- Key idea: Router works with custom page templates for app-like experiences
- Evidence: "Created quiz homepage template without header/footer using router navigation"
#### โฑ๏ธ [40:00](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=2400) โ [H2] Block Attributes and Context Integration
- Key idea: Block attributes provide page-specific data through context
- Evidence: "Time limit attribute stored as context, changes per page navigation"
#### โฑ๏ธ [45:20](https://www.youtube.com/watch?v=hlbT0fnIe8E?t=2720) โ [H3] Server Context Access Methods
- Key idea: getServerContext and getServerState provide access to new page data
- Evidence: "Get server context retrieves updated values without affecting client state"
## ๐ References
- [WordPress Interactivity API Docs](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/)
- [Block Development Examples](https://github.com/WordPress/block-development-examples)
- [Juanma's GitHub Organization](https://github.com/wama-b)
## ๐ฃ๏ธ Paraphrase
- The Interactivity Router transforms WordPress into a single-page application by updating only specific page regions instead of reloading entire pages
- Script modules provide better performance than bundled JavaScript by loading dependencies independently and on-demand
- State management allows data persistence across navigation while enabling page-specific updates through server-client merging
## ๐ฐ Newsletter
๐ **WordPress 6.9 Unlocks Single-Page Application Power**
The new Interactivity Router brings client-side navigation to WordPress core! Query Loop blocks can now navigate without full page reloads, updating only specific regions for lightning-fast user experiences.
**Key Benefits:**
- Dramatically faster navigation (no full page reloads)
- Maintains block interactivity across page changes
- Reduces bandwidth and processing overhead
- Creates app-like user experiences
**Getting Started:**
Enable the client-side navigation toggle in Query Loop block advanced settings (WordPress 6.9+). Mark regions with `data-wp-router-region` for selective updates.
**For Developers:**
Use `view-script-module` instead of `view-script` for better performance. The router dynamically loads only when needed, and state management works seamlessly across navigation.
Resources: [Interactivity API Docs](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/), [Block Examples](https://github.com/WordPress/block-development-examples), [WP-CLI](https://wp-cli.org/)
## โ
Action Items
#### WordPress
- Core: Enable interactivity router toggle in Query Loop blocks for 6.9 release
- Core Performance: Document performance benefits of script modules vs bundled JS
- Documentation: Add router region examples to Interactivity API guides
- Training: Create lessons on client-side navigation implementation
- Community: Share router examples in showcase discussions
#### DevRel
- Developer advocacy: Present router capabilities at WordCamps and meetups
- Education: Workshop on building SPA-like experiences with WordPress
- Developer experience: Improve router debugging tools and error messages
- Developer marketing: Case studies showing performance improvements
- Community management: Gather feedback on router implementation challenges
## ๐งช Hypotheses
- Client-side navigation reduces page load times by 60-80% for content-heavy sites
- Script modules improve First Contentful Paint compared to bundled JavaScript
- Router regions enable complex interactive applications while maintaining SEO benefits
- State management across navigation increases user engagement metrics
### ๐ Methodology
- A/B testing Query Loop blocks with and without client-side navigation enabled
- Performance monitoring using Core Web Vitals for router vs traditional navigation
- User engagement analysis measuring time on site and bounce rates
### โ Questions
- How does router navigation impact SEO and search engine crawling?
- What are the memory usage implications of maintaining state across navigation?
- Can router regions work effectively with third-party plugins and themes?
### ๐ฎ Future Research
- Router integration with WordPress caching layers and CDNs
- Accessibility implications of client-side navigation patterns
- Router performance with large-scale enterprise WordPress installations
### ๐ก Implications
- Practice: Developers can build app-like experiences without leaving WordPress
- Policy: Core team needs guidelines for router-compatible block development
- Security: Client-side navigation may require new CSRF protection strategies
- Education: Training needed on state management and script module optimization
- Funding: Performance improvements may reduce hosting costs for high-traffic sites
### ๐ง Learning Styles Assessment
Reading level estimate: Grade 12-14 (technical documentation level)
#### ๐ Visual learners
- Present: Code examples, network tab screenshots, DOM inspection views
- Improve: Architecture diagrams showing router data flow, state merge visualization
#### ๐ Aural learners
- Present: Live coding session with verbal explanations
- Improve: Podcast episode breaking down router concepts, audio summaries
#### ๐ฃ๏ธ Verbal learners
- Present: Clear technical explanations, analogies to React/SPA concepts
- Improve: Glossary of router terminology, comparison tables
#### ๐งฉ Kinesthetic learners
- Present: Step-by-step implementation guide, live coding demo
- Improve: Interactive playground for testing router regions, hands-on exercises
#### ๐ง Logical learners
- Present: Performance comparisons, technical architecture explanations
- Improve: Decision trees for when to use router vs traditional navigation
#### ๐งโ๐คโ๐ง Social learners
- Present: Community examples, showcase discussions
- Improve: Router implementation workshops, peer code review sessions
#### ๐งโโ๏ธ Solitary learners
- Present: Comprehensive documentation, self-paced examples
- Improve: Router implementation checklist, troubleshooting guides
#### ๐ฟ Naturalistic learners
- Present: Performance impact analogies
- Improve: Router efficiency compared to traditional web patterns
### ๐ Accessibility Assessment
#### Screen reader semantics
- Present: Proper heading structure in code examples
- Improve: ARIA live regions for router navigation announcements
#### Keyboard navigation
- Present: Router maintains keyboard focus during navigation
- Improve: Focus management guidelines for router regions
#### Contrast and readability
- Present: Code syntax highlighting with sufficient contrast
- Improve: High contrast mode compatibility testing
#### Text resizing and reflow
- Present: Responsive code examples and demos
- Improve: Router region behavior at 200% zoom verification
#### Media and captions
- Present: Live coding session with verbal explanations
- Improve: Auto-generated captions for technical terms
#### Forms and interactions
- Present: Interactive block examples maintain accessibility
- Improve: Router navigation doesn't break form context
#### Standards reference
- Router navigation should maintain WCAG 2.2 AA compliance across page transitions
### ๐ DEIB Assessment
#### Cultural breadth
- Present: Technical concepts explained in clear English
- Improve: Router examples from diverse global WordPress sites
#### Inclusive language
- Present: Avoids overly technical jargon, explains acronyms
- Improve: Plain language alternatives for complex concepts
#### Neurodiversity support
- Present: Structured presentation with clear headings
- Improve: Processing time considerations for router state changes
#### Representation
- Present: Focus on technical implementation over personal branding
- Improve: Diverse developer perspectives on router usage
#### Psychological safety
- Present: Encouraging tone about exploring new features
- Improve: Acknowledgment that router concepts can be complex
### โ
Logical Validity
#### Strong reasoning
- Deductive strength: Router reduces page loads therefore improves performance
- Inductive strength: Examples demonstrate consistent behavior patterns
- Causal reasoning: Script modules reduce bundle size leading to faster loading
- Analogical strength: Router compared to React SPA navigation effectively
#### Fallacies
- Appeal to novelty: Newer router system assumed better without complete comparison
- Hasty generalization: Limited examples may not represent all use cases
#### Tone of voice
- Overall tone: Educational and exploratory, appropriate for technical tutorial
### ๐ก๏ธ DARVO Analysis
- Deny: No denial patterns present
- Attack: No attacks on alternative approaches
- Reverse victim/offender: Not applicable
- Emotional cues and rhetoric: Positive, encouraging exploration of new features
## ๐ฏ Conclusion
The Interactivity Router represents a significant advancement in WordPress's evolution toward modern web application capabilities. By enabling client-side navigation with selective DOM updates, it bridges the gap between traditional WordPress sites and single-page applications while maintaining the platform's accessibility and SEO advantages.
The key practical takeaway is that developers can now create app-like user experiences within WordPress core functionality, particularly beneficial for content-heavy sites with pagination or multi-step processes. The performance improvements from script modules and selective region updates can significantly enhance user experience.
Looking forward, this router foundation opens possibilities for more sophisticated interactive WordPress applications while maintaining the platform's commitment to universal web access and content management simplicity.
## ๐งฑ Refactor Appendix
### ๐ Literature Split Pad
Purpose: Stage CEE units that become Literature notes.
Split level: H3
### [H1] Router enables client-side navigation in WordPress
> [!quote] [Interactivity Router](https://www.youtube.com/watch?v=hlbT0fnIe8E) by [[Juanma Garrido]] via [[YouTube]]. Published 2024-12-19. Accessed 2024-12-19.
> "Query loop block by default triggers full reload but can be set to client side navigation"
Context: WordPress 6.9 feature enabling SPA-like experiences within core blocks.
[view highlight](https://www.youtube.com/watch?v=hlbT0fnIe8E#H1) #wordpress #interactivity ID:rw_router_001
### [H2] Script modules improve performance over bundled JavaScript
> [!
---
## Full Transcript
[04:29] We are live.<br>[04:32] Hello there. How you doing?<br>[04:51] say hi in the chat if you are there.<br>[05:00] Okay.<br>[05:05] So<br>[05:07] in today's session I want to talk about<br>[05:10] the<br>[05:12] interactivity router<br>[05:15] which is a package that comes with the<br>[05:18] interactivity API.<br>[05:24] So<br>[05:26] this package is<br>[05:30] already enabled in some parts of the<br>[05:38] WordPress core blocks. For example, the<br>[05:41] query loop block.<br>[05:44] Let me try to<br>[05:48] the query loop block<br>[05:52] has a toggle and the query loop block by<br>[05:55] default it triggers a full reload of the<br>[05:59] page.<br>[06:08] But we can<br>[06:12] set this block<br>[06:15] to do a client side navigation which<br>[06:18] means<br>[06:21] that not the full page will be loaded<br>[06:23] only the specific portion of the HTML<br>[06:26] that needs to be rendered.<br>[06:29] What's the advantage of this? The HTML<br>[06:32] is going to be loaded,<br>[06:36] but the amount of HTML that is going to<br>[06:40] be processed by the browser is going to<br>[06:43] be only a little portion of it. Let me<br>[06:47] see if I can<br>[06:51] configure the query loop block<br>[06:55] to have<br>[06:58] client side navigation.<br>[07:01] So by default we come here.<br>[07:07] Okay. I only have one post.<br>[07:12] Let me create. There is this plugin<br>[07:14] called faker<br>[07:17] which I like a lot to create<br>[07:24] like to create<br>[07:26] a lot of fake post. For example, I want<br>[07:29] maybe 20 posts or something like that.<br>[07:35] I activate this.<br>[07:39] Here I can select maybe<br>[07:43] 25<br>[07:50] because by having several posts we can<br>[07:54] we can check how the query loop block in<br>[07:57] its pagination<br>[08:00] it only loads the specific<br>[08:03] portion of it.<br>[08:10] Okay. So, the posts are generated.<br>[08:15] If we go to appearance<br>[08:20] and editor<br>[08:26] in this template, for example,<br>[08:30] we have a query loop block here.<br>[08:36] If we go to the advanced<br>[08:39] section, we can see this toggle<br>[08:44] which is disabled because we are in 6.8<br>[08:51] and this is one of the new things coming<br>[08:53] in WordPress 6.9 for the<br>[08:58] for the interactivity routter.<br>[09:01] The thing is that<br>[09:04] we couldn't<br>[09:06] disable this because by default is full<br>[09:09] page. But if we disable this,<br>[09:15] we can<br>[09:18] enable client side navigation with the<br>[09:20] query loop block.<br>[09:23] But right now we are in WordPress 6.8.<br>[09:28] So, let's update. I think I'm going to<br>[09:31] lose the the posts that I have created.<br>[09:35] But anyway, let's load 6.9.<br>[09:43] Let's go to<br>[09:46] Yes, I have lost. Well, it's very<br>[09:48] quickly.<br>[09:58] Okay, I want to install this plugin.<br>[10:03] I want to activate this plugin<br>[10:06] and I want to create 25 for example.<br>[10:14] Nice. So what I want to do is<br>[10:18] to show how the query loop<br>[10:23] leverages the interactivity router<br>[10:26] package.<br>[10:29] In order to do that, I have created a<br>[10:31] lot of posts.<br>[10:36] And if we visit the site<br>[10:44] and we inspect the page<br>[10:49] and we go to network<br>[10:52] and I filter by doc.<br>[10:55] Every time that I go to a new page,<br>[10:59] I'm going to get a new<br>[11:03] doc, which means there's a full<br>[11:07] page reload. We're getting a new<br>[11:10] document, which means that<br>[11:14] the whole HTML is fetched,<br>[11:18] but also the whole HTML is processed in<br>[11:22] the browser.<br>[11:24] So a way to avoid<br>[11:27] to process the whole HTML because we<br>[11:30] don't need to process the whole HTML. We<br>[11:33] only need in this case this area.<br>[11:36] We don't need to process the header<br>[11:38] again. We don't need to process all this<br>[11:41] footer. We just need to<br>[11:44] update this specific portion.<br>[11:51] One way to do that is to enable client<br>[11:54] side navigation and the interactivity<br>[11:56] API allows that. And the query loop<br>[11:59] block<br>[12:05] allows us to do that<br>[12:07] with a toggle<br>[12:12] that can be<br>[12:16] disabled by default. The quil loop block<br>[12:19] uses like full page.<br>[12:28] So if we go<br>[12:33] edit side<br>[12:36] here we are editing this template.<br>[12:41] If we go here to query loop<br>[12:47] and we go to advanced now because we are<br>[12:50] in WordPress 6.9 we should have this.<br>[12:54] This is related to one of the<br>[12:59] updates coming in WordPress 6.9 for the<br>[13:03] interactivity router.<br>[13:07] The specific update that is related to<br>[13:11] this is this one.<br>[13:15] The thing is that it was disabled<br>[13:17] because when<br>[13:20] there was a navigation to a page that<br>[13:22] had some block<br>[13:27] that require to load the script modules<br>[13:31] that those blocks didn't work because<br>[13:33] those modules those modules weren't<br>[13:36] loaded. This has been fixed in WordPress<br>[13:40] 6.9 and<br>[13:43] this fix has allowed<br>[13:46] this feature to<br>[13:50] to be enabled. I mean now we can disable<br>[13:53] this. We can save.<br>[13:58] And when we navigate through pages using<br>[14:02] the query loop block, we will see how<br>[14:07] there's no full page reload anymore.<br>[14:12] So let's check that.<br>[14:20] If we inspect the page and we go to<br>[14:23] network,<br>[14:27] maybe what I can do is to<br>[14:33] select less elements per page.<br>[14:37] This is something that I can set here in<br>[14:39] custom.<br>[14:41] H maybe I don't know three per page.<br>[14:52] Okay, with these elements per page<br>[15:00] and if I inspect<br>[15:04] and we go to network and we filter by<br>[15:08] doc<br>[15:14] and we select next page. We can see how<br>[15:19] there's no<br>[15:21] a new document<br>[15:26] loaded directly from the browser.<br>[15:31] But what we are doing is retrieving<br>[15:37] those<br>[15:39] pages, the HTML of those pages. We are<br>[15:45] getting them<br>[15:48] by using a fetch in the background.<br>[15:51] We can see we click another one.<br>[15:55] We can see we are doing this. So the<br>[15:58] HTML is here<br>[16:02] and what the interactivity router and<br>[16:05] interactivity API is doing<br>[16:08] is<br>[16:09] getting the HTML<br>[16:12] comparing with the current HM HTML<br>[16:16] and just<br>[16:20] update the difference in that section<br>[16:24] that is defined as uh<br>[16:27] routter region I think is the the right<br>[16:29] name. Okay. So this is more or less the<br>[16:32] idea of<br>[16:34] the<br>[16:38] interactivity router. Another thing that<br>[16:41] we can do here is<br>[16:45] for example, let me go to<br>[16:50] the post one.<br>[17:00] If I edit this post<br>[17:11] And for example, I'm going to add here<br>[17:14] an image.<br>[17:20] For example, this one.<br>[17:23] And what I'm going to do is alert on<br>[17:27] click.<br>[17:30] because this<br>[17:32] behavior<br>[17:34] is powered by the interactivity EBA.<br>[17:39] So what I want to prove is<br>[17:45] this thing that<br>[17:48] when inside of<br>[17:51] router navigation, no interactivity<br>[17:54] router navigation or client navigation<br>[17:58] through the different regions.<br>[18:01] The blocks that are inside those regions<br>[18:05] can be interactive as well.<br>[18:13] Okay. If I save<br>[18:23] If I save<br>[18:40] Okay.<br>[18:41] So we have saved this post where we have<br>[18:45] added an image and that image now have<br>[18:48] lightbox behavior.<br>[18:57] So now if we go to the<br>[19:03] query loop,<br>[19:10] we can see how inside the query loop we<br>[19:14] can have this behavior working. And this<br>[19:17] is working.<br>[19:24] As you can see, it has some directives<br>[19:28] here that will be onload and blah blah.<br>[19:31] And there's also an<br>[19:37] attached to somewhere.<br>[19:45] Let me see.<br>[19:51] Touch to<br>[19:56] here.<br>[19:58] Data region rout.<br>[20:10] So the thing the thing that happened<br>[20:12] here<br>[20:15] How are you?<br>[20:21] I'm talking here about the interactivity<br>[20:24] router. All good. Good to know.<br>[20:29] Are you familiar with the interactivity<br>[20:31] routter? I've been working with um<br>[20:36] that this week a lot. I've been<br>[20:38] reviewing the documentation<br>[20:41] and I feel much more comfortable with it<br>[20:45] now. Yeah. So yeah, the thing about the<br>[20:48] interactivity routter is that<br>[20:53] it's actually applied in some parts of<br>[20:57] WordPress core. I was just explaining<br>[20:59] that<br>[21:01] in the query loop for example is<br>[21:03] implemented and it allow us to it allows<br>[21:07] us to<br>[21:10] do navigation<br>[21:14] as an<br>[21:17] single page application. You know the<br>[21:19] concept of this single page application<br>[21:21] where the navigation is controlled by<br>[21:24] the client. So we can do something like<br>[21:26] that now with the interactivity router.<br>[21:30] I have here an a really cool example.<br>[21:33] Let me see if I can find it.<br>[21:39] This is a very simple.<br>[21:43] This is something that I have borrowed<br>[21:45] from from Luis which is the<br>[21:51] mastermind behind um<br>[21:56] the interactivity API<br>[22:01] and this is a<br>[22:05] implementation of the<br>[22:10] interactivity routter and interactivity<br>[22:13] AP. PI<br>[22:17] in raw HTML. I mean we can really these<br>[22:20] are<br>[22:22] MPN components that we can use in in<br>[22:26] different environments because they<br>[22:29] encapsulate some logic and some APIs<br>[22:31] that can be used even outside of<br>[22:34] WordPress.<br>[22:35] The good thing about these packages is<br>[22:37] that they are<br>[22:40] they have been implemented<br>[22:43] with the mindset of WordPress blocks and<br>[22:46] the on the block paradigms. So they are<br>[22:49] fully compatible with how blocks work,<br>[22:53] but they can also be used outside the<br>[22:56] WordPress installation. And this is<br>[22:59] interesting if we want just to very<br>[23:01] quickly test<br>[23:05] these packages and the API they provide.<br>[23:10] For example, here<br>[23:16] we have a a little app<br>[23:21] that uses some directives of the<br>[23:24] interact 3D API but also some regions.<br>[23:29] I'm going to create here a scaly draw.<br>[23:33] I have a started here one.<br>[23:36] So this is the idea of the interactivity<br>[23:40] router. We have here<br>[23:43] um<br>[23:46] page A,<br>[23:50] we have page B<br>[23:55] and we have page C. and they are almost<br>[23:59] the same<br>[24:02] but there are some regions that I want<br>[24:04] to<br>[24:07] update. So here<br>[24:25] something like this. something like this<br>[24:29] and something like this.<br>[24:34] So we have three pages and the<br>[24:40] usual thing we would do<br>[24:45] is there any repo with um<br>[24:50] okay so mag is asking if there is any<br>[24:53] repo with examples of the interact with<br>[24:55] the API<br>[24:57] because he wants to see examples and<br>[25:00] ideas of blocks. Okay. Um yes there are<br>[25:05] let's start from the documentation which<br>[25:08] is the uh which is the best place to<br>[25:12] start. If you go to the<br>[25:17] if you go to developer.workwordpress.org<br>[25:19] you can find here different handbooks.<br>[25:21] There is one about the block editor and<br>[25:24] here in the block editor there's<br>[25:28] the documentation about interactivity<br>[25:30] API. So here in the interactivity API<br>[25:35] section I'm going to share a link in the<br>[25:40] chat<br>[25:44] at the end you can see here docs and<br>[25:46] examples and here you have some examples<br>[25:49] some really good examples<br>[25:56] for example<br>[25:59] there's a showcase discussions which is<br>[26:02] really interesting because people have<br>[26:04] been<br>[26:06] publishing here the different<br>[26:08] applications of the interactivity API.<br>[26:11] So these are here you can find a lot of<br>[26:14] ideas<br>[26:18] and another good resource is the block<br>[26:22] development examples<br>[26:26] which is this compilation of examples<br>[26:32] using the APIs provided by WordPress for<br>[26:36] blog development.<br>[26:40] I'm the main maintainer of this repo.<br>[26:42] So, I created this little app. I'm going<br>[26:46] to also share this in the chat.<br>[26:53] And the good thing is that you can very<br>[26:56] quickly<br>[26:59] find the examples you want by<br>[27:03] selecting the right tax. For example,<br>[27:04] there is attack for the interactivity<br>[27:07] API and here you have a few examples<br>[27:11] and the good thing about this app is<br>[27:13] that this page can be shared.<br>[27:18] So yeah, there are some examples here<br>[27:22] and for each example<br>[27:30] you have a live demo and you have the<br>[27:34] zip so you can download directly.<br>[27:37] This this each example is a plug-in. So<br>[27:40] you can just throw this folder<br>[27:44] into the plugins folder of your<br>[27:46] WordPress installation<br>[27:48] and you can just uh try the behavior.<br>[27:54] For example, this one<br>[27:58] interactivity API quiz block. You can<br>[28:00] see here the code<br>[28:03] and you can see here the live<br>[28:06] um<br>[28:07] live demo of that plug-in.<br>[28:10] For example, this is a a an<br>[28:13] implementation of a quiz<br>[28:16] singer of Leeppell was<br>[28:19] a plant. Yes, I'm a Leepperin fan. So,<br>[28:24] Revolver was of the of the Beatles.<br>[28:31] Yes,<br>[28:36] as you can see only when I'm controlling<br>[28:38] this on the on the client only when I<br>[28:41] have answered all the questions I can<br>[28:43] check my answers. So<br>[28:47] um okay<br>[28:52] I know the answer because I wrote the<br>[28:53] the questions. H but now we can check<br>[28:57] the answers. Okay and we can reset and<br>[28:59] then we can say single was uh whatever<br>[29:04] uh yes and whatever<br>[29:09] and we have only one correct<br>[29:12] we can. So yeah, this is an<br>[29:14] implementation and here in the code you<br>[29:17] can see how the there are two blocks<br>[29:21] actually one for each question and<br>[29:24] another one<br>[29:27] controlling the other blocks.<br>[29:30] And here in the viewjs<br>[29:33] we can see how we have different stores<br>[29:36] and different actions.<br>[29:44] And for the other one we have<br>[29:51] okay this is the this is the main one<br>[29:54] and this is each question and for each<br>[29:56] question<br>[29:58] we also have<br>[30:01] its own set of action actions its own<br>[30:05] set of state properties and so on.<br>[30:09] So yeah we can we can play and we can<br>[30:11] connect<br>[30:14] the different um<br>[30:18] different blocks. One interesting thing<br>[30:20] is that<br>[30:24] with project store<br>[30:27] FA<br>[30:35] with play store FA. One interesting<br>[30:38] thing is that these two blocks they<br>[30:40] share a specific name space. So<br>[30:44] when<br>[30:45] I define two different blocks that share<br>[30:48] a name space, I can share information.<br>[30:50] So I can do things in one block and I<br>[30:53] can make the other block to react to<br>[30:56] that to that change. So that's really<br>[30:57] cool.<br>[31:00] I think the most complex thing. Okay, so<br>[31:03] Maggot is asking um I think the most<br>[31:05] complex things right now is to<br>[31:07] understand when to use the state, when<br>[31:10] to use the context. But I but he's he's<br>[31:13] getting the thing. Yeah.<br>[31:16] Yeah. There are also in the<br>[31:19] documentation some guides and for<br>[31:22] example here<br>[31:24] it's a really good article about<br>[31:28] each concept.<br>[31:31] um<br>[31:36] that I think um<br>[31:41] yeah it provides some guidance uh in<br>[31:44] that sense.<br>[31:46] the<br>[31:48] my<br>[31:50] the way I see it right now is that<br>[31:54] the local context<br>[31:57] or the the local context makes sense<br>[32:00] when the information is only relevant to<br>[32:02] a specific portion of the DOM and that<br>[32:05] can be very small. It can be a div, it<br>[32:07] can be a ul. Um, it's a way to<br>[32:16] to isolate one portion of code only to<br>[32:21] affect a specific uh portion of the DOM.<br>[32:28] The global state makes sense when the<br>[32:36] information the state<br>[32:40] variables<br>[32:42] the<br>[32:45] all that information that I want to<br>[32:46] store and manage and modify.<br>[32:50] I wanted to affect different portions of<br>[32:54] the DOM inside a bigger inside the the<br>[32:58] inside the block inside the HTML that is<br>[33:02] managed by the block. In that case, I<br>[33:06] think the global state is interesting.<br>[33:10] It's true that we could also use like a<br>[33:13] context on the top level, but in that<br>[33:15] case, um, you can decide. The<br>[33:18] interesting thing about the global state<br>[33:21] is that you can share the information of<br>[33:24] the global state with other blocks. And<br>[33:26] that's where things get interesting.<br>[33:30] If you define local context, I don't<br>[33:33] think let me check that<br>[33:40] I don't think you can access from the<br>[33:42] outside to that information but with the<br>[33:44] global estate you can access that<br>[33:46] information<br>[33:47] from other blocks and<br>[33:54] there's this demo of this deb<br>[34:00] that showcase what is saying here. For<br>[34:03] example, here's a a block and here's<br>[34:05] another block.<br>[34:08] They both share a name space. But when I<br>[34:12] So this allows me to implement this type<br>[34:16] of effects. When I click here, this<br>[34:20] block reacts to the<br>[34:24] state variable that is in the name space<br>[34:26] that is shared by both blocks. So maybe<br>[34:31] the data has been defined here. But as<br>[34:35] this block is also defined<br>[34:39] as part of the same name space, they can<br>[34:41] share information and they can share<br>[34:44] actions and they can share callbacks and<br>[34:46] they can share everything.<br>[34:49] So yeah, this is an example and as you<br>[34:51] can see it works all the time<br>[34:55] with all the blocks.<br>[35:00] This is a really good example of of<br>[35:02] that.<br>[35:06] Okay, where was I? I think I have<br>[35:09] deviated a lot.<br>[35:12] Yeah, examples.<br>[35:15] There's also an example for<br>[35:17] interactivity router<br>[35:22] which is this one.<br>[35:31] I don't think it's the best example in<br>[35:34] the world. I have a better one now. But<br>[35:37] yeah, it's an example of an<br>[35:39] implementation. The idea here is that we<br>[35:42] can<br>[35:44] I have four posts created and I can<br>[35:46] navigate through the content of each<br>[35:48] post without doing a full<br>[35:54] reload of the page.<br>[35:58] For example, when I click next,<br>[36:04] this part<br>[36:07] doesn't change and I get<br>[36:11] the new content. And you can see here<br>[36:14] the specific attributes of the new block<br>[36:17] that is being loaded and the<br>[36:21] URL that is being loaded here.<br>[36:26] So yeah, this is an example of using the<br>[36:28] interactivity router. I have a better<br>[36:31] example now. Let me just show you that<br>[36:34] very quickly.<br>[36:47] I'm still working off on it.<br>[36:53] But if I go here to quiz. Okay.<br>[37:02] The idea<br>[37:03] I think this is a a better use case of<br>[37:05] using the<br>[37:08] interactivity router.<br>[37:10] Right now I have five posts.<br>[37:20] I have quiz and I have question one,<br>[37:22] question two, question three, question<br>[37:23] four.<br>[37:25] They are all built over a<br>[37:29] block.<br>[37:31] So the information here<br>[37:34] is<br>[37:36] inside a block and also this block has<br>[37:40] an interactive block.<br>[37:43] So I can go here and this is uh this is<br>[37:47] a block<br>[37:50] that uses the interactivity API. Well,<br>[37:53] the idea is that I can go to<br>[37:59] a page. Maybe this could make sense not<br>[38:02] as a post but as a page and then each<br>[38:05] question is a custom post type and they<br>[38:08] all share the same template. Something<br>[38:10] like that. I think it's the the best use<br>[38:12] case for this. So you can have even just<br>[38:15] a landing page. I I may do that. You can<br>[38:18] have just a landing page without any<br>[38:20] other type of navigation and you just<br>[38:22] enter directly into this quiz.<br>[38:26] And right now I'm randomly selecting<br>[38:29] questions.<br>[38:32] And when I start<br>[38:35] each question has a time remaining<br>[38:38] and I cannot navigate<br>[38:42] I cannot navigate anymore to this<br>[38:45] question and I have 10 seconds<br>[38:49] right now. I don't have a way to provide<br>[38:52] an answer. I just want to test the<br>[38:57] interactivity router and the navigation.<br>[39:02] But yeah, this is working fine.<br>[39:07] And we can see<br>[39:11] here<br>[39:15] if we go reset quiz well I can share the<br>[39:22] repository where I have this<br>[39:25] which is in<br>[39:30] by the way<br>[39:32] if you are interested in following what<br>[39:36] I'm doing lately I have implemented this<br>[39:40] thing in my<br>[39:43] GitHub profile<br>[39:49] which actually I have like different<br>[39:51] GitHub profiles because<br>[39:54] my GitHub username is actually<br>[39:59] one my guitar<br>[40:03] but I have different organizations to<br>[40:05] organize is the different areas um I've<br>[40:10] been working during my career.<br>[40:15] So when I started focusing more on<br>[40:17] WordPress,<br>[40:20] I created this Jamavp<br>[40:24] organization and here's where I do most<br>[40:27] of my work. Okay. So in this<br>[40:29] organization I have a landing page that<br>[40:33] shares the activity I have had lately.<br>[40:40] For example, I automatically share here<br>[40:43] the latest posts that I publish. I have<br>[40:48] here my feature projects which are like<br>[40:51] the<br>[40:53] yeah the most interesting projects that<br>[40:56] I have and<br>[40:59] and you can see the activity I do on<br>[41:01] them but also I share here the<br>[41:07] repositories that I have created lately.<br>[41:10] So here you can see<br>[41:14] the repository with the project I'm<br>[41:17] showing you. I going to share this in<br>[41:21] the chat as well<br>[41:29] and also some<br>[41:32] repositories that I start and also some<br>[41:36] guests that I have.<br>[41:39] For example, this is a G that I use a<br>[41:42] lot.<br>[41:46] This is a a way a very quick way to<br>[41:48] detect<br>[41:52] to check if the custom blocks that I<br>[41:56] have defined are properly registered. If<br>[41:59] I in this,<br>[42:03] if I go to the block editor, I need to<br>[42:05] be in the block editor,<br>[42:08] which means I need to have access to the<br>[42:11] doll BP global window. I can just launch<br>[42:14] this and this tells me the custom blocks<br>[42:19] that it so it goes through the list of<br>[42:23] all registered blocks and excludes from<br>[42:27] that<br>[42:29] array of objects. It excludes the core<br>[42:32] blocks. So it just returns the custom<br>[42:36] blocks. So this is a pretty useful<br>[42:40] snippet that I<br>[42:43] use from time to time.<br>[42:48] So yeah, I was<br>[42:50] sharing this because I wanted<br>[42:54] to share this repository with this<br>[42:56] example, but also if you want to<br>[42:59] to check some other things I've been<br>[43:01] working on lately, you can directly go<br>[43:03] to github.com/wama-b.<br>[43:09] Perfect.<br>[43:11] Let's continue.<br>[43:17] with this demo. If I go to rest quiz um<br>[43:24] we can see here in the console<br>[43:27] in the elements.<br>[43:34] So this is<br>[43:36] when we navigate through different<br>[43:40] pages. I have here defined a<br>[43:43] interactivity routter region quiz. So<br>[43:46] this is the portion that is going to be<br>[43:48] updated whenever I navigate. As you can<br>[43:51] see if I go to question one<br>[43:55] you can see how things here have been<br>[43:59] highlighted which means that only this<br>[44:02] portion of the DOM has been<br>[44:05] processed and updated. So this is the<br>[44:07] interesting thing. The whole page hasn't<br>[44:10] changed.<br>[44:12] And the only<br>[44:14] portion of HTML that has been updated in<br>[44:17] the browser is this uh new elements. So<br>[44:21] there's a div happening and the new<br>[44:23] parts inside this section are the ones<br>[44:27] that are updated.<br>[44:30] Okay.<br>[44:32] Okay. Let me close<br>[44:36] conversations<br>[44:38] because I'm just uh jumping from one<br>[44:41] thing to another.<br>[44:43] But that's fine. This is just sharing<br>[44:46] the stuff out loud.<br>[44:51] Um okay, I have shared the samples.<br>[44:55] I have shared this. I have shared this<br>[44:58] and we were checking the documentation<br>[45:02] about the<br>[45:05] global state local context and derived<br>[45:08] state<br>[45:10] and I was here.<br>[45:15] When we navigate through pages,<br>[45:23] we usually do that by clicking links and<br>[45:26] that provokes a full<br>[45:31] page reload. But the<br>[45:39] the activity API router, if we go to the<br>[45:42] documentation, which is this one,<br>[45:54] the interactivity API routter provides<br>[45:58] two<br>[45:59] methods, two actions. One of the actions<br>[46:02] is navigate.<br>[46:04] And the navigate<br>[46:10] method what it does is it fetches the<br>[46:15] page HTML<br>[46:19] and updates any interactive regions<br>[46:22] whose contents have changed in the new<br>[46:24] page.<br>[46:28] So if I navigate using normal navigation<br>[46:30] the whole<br>[46:32] content is updated. But if I if I use<br>[46:42] navigate<br>[46:52] from the interactivity routt<br>[47:00] Put that.<br>[47:31] Then what happens is<br>[47:38] the following. I fetch<br>[47:42] the HTML<br>[47:45] of the new page.<br>[48:01] Um, what I can do this? Okay, I'm going<br>[48:04] to do this.<br>[48:08] Do this<br>[48:10] full full um full.<br>[48:17] Okay,<br>[48:19] then<br>[48:31] one.<br>[48:42] Nice.<br>[48:51] So I have this<br>[48:54] going to group<br>[49:04] to create like different steps.<br>[49:16] We fetch the HTML of the new page. Then<br>[49:21] we<br>[49:33] um get the<br>[49:41] the region. How is this called? Uh this<br>[49:46] we get<br>[49:49] extract<br>[49:53] extract the<br>[49:55] region<br>[50:03] and<br>[50:20] Update in the DOM<br>[50:24] only<br>[50:26] the new<br>[50:29] the new parts<br>[50:33] in<br>[50:35] the<br>[50:37] under the<br>[50:40] in the<br>[50:43] in the R region.<br>[50:48] This is um the part of the interactivity<br>[50:52] API<br>[50:55] that leverages React.<br>[51:12] So I'm going to say here<br>[51:16] react.<br>[51:37] Mhm.<br>[51:40] React is like a React. So this is more<br>[51:43] or less what a React application is<br>[51:45] doing.<br>[51:49] And every time I go to a new page using<br>[51:52] navigate, this is what's uh going on.<br>[51:56] So there's no a full page reload. only<br>[52:00] the HTML is fetched via<br>[52:05] a fetch in the background and only not<br>[52:08] all the HTML is updated in the browser<br>[52:13] only a specific portions.<br>[52:15] How do we define those portions? By<br>[52:18] using the data lip routter region.<br>[52:26] So if we go to the application<br>[52:53] see if I can show<br>[53:00] Yeah, this is the code.<br>[53:17] This is the code.<br>[53:22] Um<br>[53:25] This is the code that I have and the<br>[53:28] demo is<br>[53:32] here.<br>[53:47] Okay, this is the<br>[53:54] And here what I have is a a block using<br>[53:58] interactivity API.<br>[54:03] To define a block with the interactivity<br>[54:05] API, we need to mark the block as<br>[54:10] supports interactivity true.<br>[54:39] This is one of the requirements supports<br>[54:41] interactivity true.<br>[54:47] Then we need to create<br>[54:51] another thing is in the block.json JSON<br>[54:53] we need to define a view script module.<br>[55:00] This will make that in the build process<br>[55:03] the<br>[55:05] bundle<br>[55:07] will be prepared to be loaded as a<br>[55:10] module in the in the client in the<br>[55:12] browser.<br>[55:16] Which means that<br>[55:19] if I go here<br>[55:29] for example the BUJS imports the<br>[55:35] WordPress interactivity<br>[55:39] package<br>[55:42] if I don't<br>[55:47] use the experimental modules flag.<br>[55:51] What happens in the build process when I<br>[55:53] do WB scripts build<br>[55:59] is that this library gets bundled with<br>[56:02] the final<br>[56:05] JavaScript<br>[56:06] which means that the JavaScript is going<br>[56:08] to be bigger.<br>[56:12] When we use the experimental modules,<br>[56:15] what we do is<br>[56:22] we serve this<br>[56:25] JavaScript as a JavaScript module in the<br>[56:29] browser. The browsers can manage<br>[56:31] directly modules.<br>[56:34] So in the bundle<br>[56:37] this<br>[56:40] library is not going to be bundled in<br>[56:43] the final JavaScript. So the Vue.js is<br>[56:46] going to be lighter. So it's going to<br>[56:50] have less size. We can see here<br>[56:57] the Vue.js JS. It basically only<br>[57:01] contains um<br>[57:06] our code.<br>[57:11] Yeah, it doesn't<br>[57:14] it doesn't contain anything else. And we<br>[57:17] can see here that we have an import<br>[57:20] that is going to be managed directly by<br>[57:23] the browser. So<br>[57:26] when we serve JavaScript modules<br>[57:30] and the blocks<br>[57:34] provides different ways to do that<br>[57:39] very easily.<br>[57:42] So what do we need to do to serve a BUJS<br>[57:46] in a block as a module? The only thing<br>[57:48] we need to do is to<br>[57:51] define this view. JS as a view script<br>[57:55] module. And<br>[57:58] when we do the build, we just<br>[58:03] add the flag experimental modules. When<br>[58:06] we do that, any import that we<br>[58:12] use in the Vue.js s is going to be<br>[58:15] imported directly in the browser.<br>[58:20] So let's check that. If we go to the<br>[58:24] demo<br>[58:26] when I load,<br>[58:29] let's see<br>[58:32] network.<br>[58:37] Let's go to quiz.<br>[58:43] Okay, we can see how<br>[58:56] we can see how the<br>[58:59] interactivity API<br>[59:02] engine is loaded independently. It's<br>[59:05] loaded before because there is a preload<br>[59:08] of the code. If we go to sources, no, if<br>[59:12] we go to elements,<br>[59:15] we can see here that the<br>[59:20] direct<br>[59:21] GBT<br>[59:29] API<br>[59:35] reload.<br>[59:38] Yeah, we can see here how there's a<br>[59:40] module preload which means that is<br>[59:43] loaded<br>[59:45] independently but it's loaded<br>[59:48] just when the page starts loading and<br>[59:52] then WordPress at some point WordPress<br>[59:55] at some point it does the NQ script. So<br>[59:59] that's where the<br>[60:04] that's where the<br>[60:10] let me see<br>[60:16] this is the one of the<br>[60:21] block library I guess maybe it's the<br>[60:23] navigation<br>[60:24] then we have the interactivity router<br>[60:31] Wait.<br>[60:41] Uh, why can't it see<br>[60:44] address? I'm going to<br>[60:47] address. What else?<br>[60:51] Type script.<br>[60:56] Yeah, this is the one of our plug-in<br>[61:00] and the interactivity API.<br>[61:04] So I have those packages loaded and then<br>[61:08] also the<br>[61:10] the navigation navigation it loads<br>[61:14] also like its own<br>[61:17] module.<br>[61:19] So here's the views of our plug-in. And<br>[61:23] one of the cool thing<br>[61:26] One of the cool things of JS modules is<br>[61:29] that I can<br>[61:31] I can load. So in this case, let me see<br>[61:35] if we can we can have here a diagram. So<br>[61:39] we have the<br>[61:43] inter the activity interactivity<br>[61:50] API<br>[61:52] JS module<br>[61:56] module<br>[62:01] um<br>[62:03] which is basically the<br>[62:06] activity API engine the JavaScript that<br>[62:10] contains all the logic behind the<br>[62:12] interactivity API. This is a module.<br>[62:16] This is um pre preloaded<br>[62:21] when the page<br>[62:23] uh starts<br>[62:26] uh starts<br>[62:28] being loaded<br>[62:31] in the browser.<br>[62:36] The page starts being loaded in the<br>[62:39] proofs.<br>[62:46] Okay,<br>[62:49] this is um<br>[62:57] one<br>[62:59] model.<br>[63:01] Then we have the<br>[63:09] the Vue.js<br>[63:15] the Vue.js file of our block of our<br>[63:20] custom block.<br>[63:30] This<br>[63:32] Vue.js has import.<br>[63:39] It has this<br>[63:42] import<br>[63:44] blah blah blah.<br>[63:54] It has this import blah blah blah.<br>[63:58] So whenever<br>[64:01] this happens,<br>[64:12] it<br>[64:14] automatically imports<br>[64:18] the<br>[64:21] JS model because it's already in the<br>[64:23] browser. It has been it has been loaded.<br>[64:28] has been preloaded.<br>[64:38] But then at some point the code it<br>[64:44] does this<br>[64:47] which is really cool because when we<br>[64:56] trigger the navigation<br>[64:59] and what's happening here in the code is<br>[65:02] that at some point in the on click<br>[65:07] in the on click we do navigate. So this<br>[65:11] is the navigation<br>[65:15] managed by the interactivity API router.<br>[65:18] This is when we are enabling this type<br>[65:21] of navigation.<br>[65:24] So what's happening is when we do on<br>[65:28] click<br>[65:30] here<br>[65:34] we are dynamically loading the package<br>[65:37] that<br>[65:40] contains the logic of the interactivity<br>[65:42] router which is also super performant.<br>[65:49] And we have this<br>[66:07] We have this<br>[66:12] and this<br>[66:14] it<br>[66:17] going to<br>[66:19] provoke the loading. in of another<br>[66:23] package<br>[66:30] but only<br>[66:34] only when there's a click in that<br>[66:37] element.<br>[66:39] So as you can see all the<br>[66:43] APIs and all the workflows that are<br>[66:48] encouraged by the interactivity API and<br>[66:54] working in the background<br>[66:58] are very performant. They are thought<br>[67:00] with performance in mind like uh making<br>[67:04] the<br>[67:07] requests and the process of HTML in the<br>[67:12] most effective way.<br>[67:17] Okay. Nice.<br>[67:22] So<br>[67:24] when I do click and in our example we<br>[67:29] were doing that here.<br>[67:31] When I click on any of these elements<br>[67:40] and I can see this in the code here.<br>[67:48] I have a random selection of URLs<br>[67:54] that I am<br>[67:58] adding to the state.<br>[68:02] I'm doing that here. random question<br>[68:05] slacks<br>[68:08] and using these directives I'm<br>[68:12] creating a loop and for each value I'm<br>[68:15] creating a link<br>[68:21] the text is managed by a state variable<br>[68:24] this is actually a derived state because<br>[68:27] item slack if I go<br>[68:30] here item slack as you can see this is<br>[68:33] derived state<br>[68:35] which means that I am getting the<br>[68:37] context and for each item in the context<br>[68:40] I'm doing something to generate the<br>[68:43] final text.<br>[68:48] Okay, but the interesting thing is this<br>[68:51] actions navigate because every time I<br>[68:54] click on these links I'm not going to do<br>[68:57] a full page reload. I'm going to do a<br>[68:59] client side navigation<br>[69:02] because actions navigate here<br>[69:07] is this.<br>[69:11] So what I'm doing here is I'm accessing<br>[69:14] the DOM element that<br>[69:18] triggered this method.<br>[69:24] I'm preventing the default. So the<br>[69:29] default event in the browser doesn't get<br>[69:32] triggered is if I do if I don't do this<br>[69:37] I will<br>[69:39] get a full page reload. So I need to do<br>[69:42] this to stop any behavior<br>[69:47] in the browser because it's like saying<br>[69:49] it's like saying hey don't do anything<br>[69:51] else. I'm going to take control of<br>[69:52] things from now on. So what I'm doing is<br>[69:56] I dynamically import the<br>[70:02] interactivity router and then I navigate<br>[70:05] using the<br>[70:09] actions uh navigate<br>[70:13] from the interactivity router. This is<br>[70:16] something that is documented here. If we<br>[70:19] go to the documentation,<br>[70:22] we can see how the package interactivity<br>[70:25] API exposes two methods. The navigate<br>[70:29] method and the prefetch method.<br>[70:39] And the navigate method what it does is<br>[70:42] uh this is it fetches the HTML of the<br>[70:45] new page.<br>[70:47] It extracts the specific router region<br>[70:50] and it updates the<br>[70:57] the portion of the DOM that has been<br>[70:59] updated.<br>[71:01] Nice.<br>[71:08] What else we can show from this demo?<br>[71:12] Okay, another interesting idea behind<br>[71:15] this um<br>[71:18] is the concept of<br>[71:23] a state in the client and a state in the<br>[71:26] server<br>[71:28] because with the interactivity API<br>[71:33] we can define a state in the client. For<br>[71:36] example, here<br>[71:41] I have these props that are defined in<br>[71:45] the state.<br>[71:47] We have a name space which is<br>[71:49] interactivity router region quiz<br>[71:53] and under this name space I can define<br>[71:57] state variables. I can define actions<br>[71:59] call backs<br>[72:03] and here I'm defining these props<br>[72:07] visited question slacks current timer<br>[72:10] page<br>[72:12] this is something that I'm defining in<br>[72:14] the client<br>[72:17] but when the page is loaded I'm also<br>[72:20] passing some initial values from the<br>[72:24] server<br>[72:28] And what's happening here is that<br>[72:34] for every page<br>[72:45] I'm going to put this<br>[73:10] This is the client.<br>[73:20] This is the client<br>[73:25] and this is the server.<br>[73:49] Let me choose this. This is the server<br>[73:54] to be blue. This is going to be green.<br>[73:57] Okay.<br>[74:02] So for the same name space let's call it<br>[74:05] a name space<br>[74:10] a<br>[74:14] or the same name space<br>[74:24] I have um state<br>[74:35] Let me adjust this a little bit. Going<br>[74:39] to put this here.<br>[74:41] Okay. So, this is a state<br>[74:44] or name space<br>[74:48] opposite. This is going to be the name<br>[74:50] space<br>[74:53] and the state is this.<br>[75:00] So we have defined a state in the<br>[75:07] in the server<br>[75:12] and and<br>[75:18] the client.<br>[75:21] So when<br>[75:26] when the page is loaded, I have some<br>[75:28] initial<br>[75:31] values coming from the server<br>[75:34] which is<br>[75:37] what I define with the WP interactivity<br>[75:40] state. This allows me to define some<br>[75:44] initial values from the server<br>[75:47] and then when the JavaScript is loaded,<br>[75:50] I can also define some values in the<br>[75:53] client like for example this. What's<br>[75:56] happening here is that there is a merge<br>[76:01] happening.<br>[76:09] There is a merge happening.<br>[76:15] And what I got here is<br>[76:30] whatever came from the<br>[76:35] Whatever came from the server<br>[76:38] plus whatever was defined in the client.<br>[76:47] Going to express this<br>[76:50] a bit better.<br>[77:07] Mhm.<br>[77:15] I'm going to<br>[77:17] express this a bit better.<br>[77:23] Um,<br>[77:28] put this<br>[77:30] like this and<br>[77:33] this.<br>[77:41] Yeah, I think this is better.<br>[77:51] Something like this is better.<br>[77:54] A bit more clear.<br>[78:03] So we have some initial state in the<br>[78:06] server. Then we have some initial state<br>[78:09] in the client. And we merge both. And in<br>[78:12] the client I finally have the<br>[78:17] two<br>[78:19] um<br>[78:22] the merge of the two states.<br>[78:25] But what happens when we do this<br>[78:28] navigation?<br>[78:32] I can have something similar.<br>[78:42] So I can have here<br>[79:02] I can have here<br>[79:10] some name space.<br>[79:20] That is the result of<br>[79:24] is the result of<br>[79:27] this<br>[79:31] if the result of<br>[79:35] okay let me put this here and I'm going<br>[79:38] to put this here<br>[79:43] so we have in page<br>[79:45] A a state in the client that is result<br>[79:48] of<br>[79:50] the initial state defined in the server<br>[79:56] with this function plus the initial<br>[80:00] state defined in the client<br>[80:04] here.<br>[80:21] Okay.<br>[80:45] Mhm.<br>[81:00] So, what happens when we navigate to a<br>[81:03] new page<br>[81:07] that has<br>[81:10] a new state<br>[81:30] It has a new state.<br>[81:49] because now we have um<br>[81:54] two different states<br>[81:57] and we don't want to automatically<br>[82:00] merge this because maybe we want to<br>[82:04] maybe use the<br>[82:08] val we are<br>[82:13] managing through the whole navigation.<br>[82:15] For example, in the quiz, I may want to,<br>[82:20] I don't know, keep track of the<br>[82:25] keep track of the different<br>[82:29] responses of the the the yes or nos or I<br>[82:33] don't know.<br>[82:37] For example, um<br>[82:42] in this example,<br>[82:45] the initial<br>[82:49] page.<br>[82:51] Yeah,<br>[82:53] you can see how the first time the page<br>[82:55] is loaded, the<br>[82:58] state server and the state in the client<br>[83:00] is the same.<br>[83:04] Well, in other words, the properties and<br>[83:09] the values that we have in the server<br>[83:12] match the ones we have in the client<br>[83:14] because there is a merge of the<br>[83:16] properties that we have defined for the<br>[83:19] server<br>[83:21] which represents this<br>[83:27] with the properties we have defined in<br>[83:30] the client. We sends this and in the<br>[83:34] code this is the properties that we have<br>[83:36] defined the client<br>[83:39] and this is<br>[83:41] but what happens if navigate to a new<br>[83:44] page I have the<br>[83:49] global state in the client but I do<br>[83:52] something like this for a specific pages<br>[83:56] I want to add some information maybe I<br>[83:59] want to add some new fields<br>[84:01] or maybe I want to initialize some data<br>[84:05] for a specific<br>[84:08] URLs.<br>[84:10] So in that situation I have a new state<br>[84:14] in the server<br>[84:17] defined for that page and then I have<br>[84:20] still some value in the client.<br>[84:26] What what's happening in this case? This<br>[84:29] is explaining the documentation<br>[84:34] somewhere.<br>[84:38] If we go to API reference, I think it's<br>[84:50] um okay, I think it's better explained<br>[84:54] here.<br>[85:14] Let me<br>[85:16] have a look at again here. Store client<br>[85:19] methods.<br>[85:39] I think maybe it's in the interactivity<br>[85:42] router.<br>[85:45] Interactivity<br>[85:50] router. If we go to the package<br>[85:55] to the interactivity routter<br>[85:58] package.<br>[86:08] No, this is not explained. This is<br>[86:09] something that<br>[86:11] um needs to be added to the<br>[86:14] documentation. So what's happening right<br>[86:16] now is that there is um<br>[86:22] soft merge happening right now.<br>[86:35] There is a soft merge happening right<br>[86:37] now.<br>[86:50] which means<br>[86:53] that new properties will be added<br>[86:56] directly to the<br>[86:59] global state in the client but new<br>[87:03] values for existing properties<br>[87:07] will not be merged. So we will have for<br>[87:11] the same properties we will have one<br>[87:14] value in the server and another value in<br>[87:18] the client.<br>[87:20] So how do we<br>[87:23] access the<br>[87:25] values coming from the state? So that's<br>[87:30] why we have these methods available<br>[87:34] which are get server<br>[87:39] context, get server state. In this case<br>[87:42] it would be get server state.<br>[87:50] Get server state.<br>[87:53] Get server state.<br>[88:01] We get server state. I can access<br>[88:10] I can access this<br>[88:23] and I can decide what to do.<br>[88:27] with these<br>[88:29] values.<br>[88:31] So get server state retrieves the server<br>[88:33] state in an interactive region. This<br>[88:36] function serves the same purpose as get<br>[88:40] server context. We have a similar<br>[88:43] function for the context<br>[88:47] but it returns the state.<br>[88:50] The object returned is read only and<br>[88:53] includes the state defined in PHP with<br>[88:56] WBP interactivity state<br>[89:00] which is this case.<br>[89:02] We have a default<br>[89:05] state defined in the server. But for a<br>[89:08] specific<br>[89:10] URLs I have some<br>[89:13] modified values. For example, extra data<br>[89:18] is<br>[89:23] different from the server for each URL.<br>[89:27] But then I have new fields happening<br>[89:30] here.<br>[89:34] So when using actions navigate the<br>[89:37] object returned by get server state is<br>[89:39] updated to reflect the changes<br>[89:45] in its properties<br>[89:48] without affecting the state returned by<br>[89:50] star<br>[89:52] and we can subscribe to those changes to<br>[89:55] update the state if needed.<br>[90:02] So if we start the navigation here<br>[90:08] the first time we can see how the state<br>[90:10] that comes from the server<br>[90:14] is completely merged with the properties<br>[90:19] that and the values we have defined for<br>[90:21] the state in the client.<br>[90:25] So we can make a difference between the<br>[90:27] state server and a state. But at the end<br>[90:29] that we can directly work with this.<br>[90:35] But then we go to question one<br>[90:40] and we can see for example<br>[90:43] how the extra data property it has a<br>[90:48] different value than the one stored in<br>[90:53] the client state in the client global<br>[90:55] state. So here's where this function<br>[91:01] comes handy. this one get server state<br>[91:05] because with get server state we can<br>[91:07] access the new values and decide what to<br>[91:11] do with them. Maybe I want to update<br>[91:14] this property with the new value or<br>[91:16] maybe I don't but I can decide to do<br>[91:18] that manually.<br>[91:22] In the case of the new fields they are<br>[91:25] automatically added to the state because<br>[91:28] they are not affecting anything.<br>[91:32] So<br>[91:35] this this is how it works.<br>[91:40] This<br>[91:48] um<br>[91:55] Okay, I'm going to put this here.<br>[92:04] Okay, nice. So, let's work a little bit<br>[92:06] on this uh project.<br>[92:23] Let's go through the logic.<br>[92:26] For example, one thing that I want to<br>[92:28] solve,<br>[92:33] maybe I want to create<br>[92:40] I want to create a template.<br>[92:48] Let me see if I'm able to create a<br>[92:50] template custom template.<br>[92:53] So if we go to<br>[92:57] the editor<br>[93:02] and we go to templates<br>[93:04] right now we are using the single post.<br>[93:17] So what I want to do is to<br>[93:31] okay one maybe I'm not stealing<br>[93:33] WordPress 6.9.<br>[93:43] Yes I'm in WordPress 6.9.<br>[93:46] Okay. So, I thought there was a way to<br>[93:52] duplicate templates.<br>[93:56] Edit<br>[93:59] single posts.<br>[94:07] Can I create?<br>[94:14] Okay, let me see.<br>[94:17] If I go to the post<br>[94:20] to the quiz post<br>[94:24] the template is single post. Um<br>[94:32] create new template<br>[94:35] uh custom<br>[94:37] with template.<br>[94:42] Okay.<br>[94:47] Group content.<br>[94:54] Mhm.<br>[94:58] Okay. I'm going to try just this to see<br>[95:01] what happens. This is the<br>[95:04] custom quiz template.<br>[95:17] And I want to create a page<br>[95:21] that I'm going to call<br>[95:26] with<br>[95:29] contest.<br>[95:33] And this page I wanted to use<br>[95:38] the custom quiz template.<br>[95:47] Okay.<br>[95:49] And<br>[95:51] if I go to the page, I have<br>[95:55] nothing<br>[95:57] because<br>[96:00] I need to edit the page.<br>[96:03] And I'm going to edit the page<br>[96:07] with the content of the quiz.<br>[96:17] So I'm going to copy this<br>[96:21] and I'm going to go to the page<br>[96:25] with contest.<br>[96:32] And I'm going to put this here.<br>[96:39] So whenever I go to the page, I have<br>[96:41] this.<br>[96:44] So no WordPress, no header, no footer.<br>[96:48] The thing is that if I go here, let's<br>[96:51] see what happens. I think it's not going<br>[96:54] to work well, but<br>[96:59] okay. It worked well.<br>[97:02] Nice.<br>[97:07] Then have this here.<br>[97:17] And if I<br>[97:21] go to quiz context,<br>[97:26] maybe I can just uh in the dashboard<br>[97:34] in the settings general.<br>[97:43] Um,<br>[97:46] how do I define<br>[97:51] in the<br>[97:53] site editor that I want<br>[97:56] this page as a front page?<br>[98:01] It should be somewhere here. Customize<br>[98:09] homepage settings.<br>[98:12] static page<br>[98:15] with context<br>[98:18] publish.<br>[98:23] Nice. So whenever I go here<br>[98:27] I'm going to log out.<br>[98:39] Whenever I go to the homepage, I have<br>[98:42] this application. I have can go to<br>[98:45] question two.<br>[98:56] I go to question three<br>[99:05] and I can reset the quiz.<br>[99:11] Nice. I like that. It feels like a<br>[99:16] like a page done with any other<br>[99:19] framework.<br>[99:28] Okay. One thing that I want to do is<br>[99:30] that<br>[99:33] when<br>[99:36] the time gets to zero,<br>[99:43] okay, times up. That's fine.<br>[99:50] But I want to exclude the first page for<br>[99:54] that because by default<br>[99:56] this is zero, I think. And I want to<br>[99:59] solve that.<br>[100:03] I haven't found a way. This should be<br>[100:05] simple, but I haven't found a way<br>[100:09] so far to do that.<br>[100:15] This is the<br>[100:17] portion of HTML that is displaying that<br>[100:21] text which is dynamically created<br>[100:27] with a derived state called timer text.<br>[100:35] and timer text<br>[100:48] should return<br>[100:53] empty string whenever the timer is less<br>[100:57] than zero. And that's why by default<br>[101:13] By default the<br>[101:20] time limit<br>[101:23] the time limit is defined I haven't<br>[101:25] explained this the time limit<br>[101:29] going to close this this This. This.<br>[101:42] And this.<br>[101:45] This.<br>[101:53] I'm going to go to WordPress studio,<br>[101:57] which is here. And I'm going to get the<br>[102:00] password of the admin.<br>[102:03] So I can log here.<br>[102:06] It's admin<br>[102:15] and<br>[102:28] what I wanted to show is<br>[102:35] yeah that for each post and for each<br>[102:39] question<br>[102:43] I'm using the same block and the blocks<br>[102:48] each block has an attribute<br>[102:53] you can see this in the code here<br>[102:56] there's an attribute defined called time<br>[102:58] limit and the edit function is providing<br>[103:03] an inspector control area to<br>[103:08] allow the user to edit that value.<br>[103:13] So whenever I edit<br>[103:17] this value and I save for example<br>[103:22] this value for question four when I save<br>[103:26] it starts in 10.<br>[103:31] This<br>[103:32] value is stored as an attribute for the<br>[103:35] block<br>[103:43] and and<br>[103:49] set quiz. And if I go to question four,<br>[103:57] the timer starts in 10.<br>[104:00] Because<br>[104:04] in the render PHP, we are<br>[104:09] getting this value from the attributes<br>[104:11] of the block. We are setting the time<br>[104:14] limit.<br>[104:15] The time limit variable<br>[104:21] is used to define the context for each<br>[104:25] block.<br>[104:33] Why the context? Because this is a value<br>[104:36] that makes sense only for each block. I<br>[104:39] don't really want to share that<br>[104:41] globally. So I think it makes sense to<br>[104:43] be part of the context and that's why<br>[104:46] I'm defining<br>[104:49] this here by using the DBP interactivity<br>[104:54] data BP context.<br>[104:58] So this time limit<br>[105:02] every time<br>[105:05] I load a page.<br>[105:16] I can see how it's part of the<br>[105:20] data context of each block.<br>[105:46] Nice.<br>[105:50] And if I go to question three,<br>[105:54] we can see how this changes and we can<br>[105:58] get this value.<br>[106:03] So the state in the client<br>[106:06] is merged with the state that<br>[106:11] is provided by the server. there's a<br>[106:13] merge and um<br>[106:18] there's a soft merge in the case of<br>[106:20] navigation but because this property<br>[106:26] property<br>[106:33] time limit let me see<br>[106:37] we go to the console reset quiz this.<br>[106:45] It's in the context. It's in the<br>[106:47] context.<br>[106:52] If I go to question one,<br>[107:01] time limit 22 and time limit 22.<br>[107:12] Okay, this is interesting because the<br>[107:16] time limit that was in the<br>[107:24] in the context<br>[107:39] the fault field.<br>[107:44] Okay, let me do one test.<br>[107:48] I want to do one test. So these<br>[107:52] properties instead of defining them as<br>[107:55] part of the state, I want to define them<br>[107:58] as part of the context.<br>[108:17] H<br>[108:19] extra data now in the client. Well,<br>[108:22] let's see what happens with this.<br>[108:26] Let's see what happens with this. If I<br>[108:29] go to here<br>[108:32] set quiz or just the<br>[108:52] Okay, I need to<br>[108:54] No, I'm doing this already.<br>[108:58] So in the building the quiz I should<br>[109:01] have this as part of the context. Nice.<br>[109:06] And<br>[109:08] so current SL context extra<br>[109:13] data.<br>[109:18] Ah okay.<br>[109:21] No, I need to<br>[109:29] I need to do this here.<br>[109:33] I create the array and then I add the<br>[109:35] extra properties.<br>[109:42] Let's see what happens here.<br>[109:47] Okay. What I want to check<br>[109:52] Is that now<br>[110:00] why is this uh provide maybe it's cached<br>[110:04] something<br>[110:06] if I do a full reload.<br>[110:15] Okay,<br>[110:16] let's do<br>[110:20] the problem that I'm having is that I am<br>[110:23] defining this extra data.<br>[110:30] Ah, okay.<br>[110:33] Ah, okay. Because this extra data and<br>[110:37] the full fields were defined for the<br>[110:39] state. Okay. Yeah, it works as as<br>[110:43] expected.<br>[110:47] Okay. Now is the context in the server.<br>[110:50] Default field, default value, default<br>[110:51] data, default value, default data, chain<br>[110:54] limit and so on. If I go to question<br>[110:58] one,<br>[111:07] the context server provides this new<br>[111:09] value<br>[111:18] that is<br>[111:24] updated. did but the question one data<br>[111:29] is not<br>[111:34] merged.<br>[111:39] This is something that I need to<br>[111:42] clarify.<br>[111:44] Clarify. Yeah.<br>[111:48] Why are some values being merged?<br>[111:55] So time limit<br>[112:04] um<br>[112:08] because on every new navigation<br>[112:12] ah okay yeah I know why I know why<br>[112:16] because I'm<br>[112:18] in the viewjs<br>[112:22] I'm specifically updating the context.<br>[112:26] Yeah, that's why because if I don't do<br>[112:29] this,<br>[112:32] if I don't do this,<br>[112:38] I guess I would get the previous value.<br>[112:45] CTX is not defined because somewhere<br>[112:48] here. Okay, let me<br>[112:53] Let me comment this.<br>[112:57] Let me comment this.<br>[113:02] Okay. Question one<br>[113:06] 21 20.<br>[113:19] Um, no. What I can do here is console<br>[113:22] text and context instead of updating.<br>[113:27] Let's analyze this.<br>[113:29] Let's analyze this.<br>[113:34] Okay, first<br>[113:36] load of the page. What we have here is<br>[113:40] context from the server.<br>[113:45] what I'm getting from the server because<br>[113:48] this is the first load all of this is<br>[113:50] automatically merged in the client and<br>[113:54] because in the client I don't have any<br>[113:56] specific<br>[113:58] context<br>[114:04] define<br>[114:06] well the okay here it makes no sense<br>[114:11] okay it makes no sense<br>[114:13] because I have one context in the client<br>[114:16] for the first time.<br>[114:24] But then every time I rewrite,<br>[114:30] let me see if I go to question one.<br>[114:36] So now I have the context from the<br>[114:39] server that contains the new time limit,<br>[114:44] the new field and extra data.<br>[114:52] But in the client the<br>[114:56] uh yeah<br>[114:59] so the previous context remains as you<br>[115:03] can see the previous context remains<br>[115:06] here.<br>[115:10] So we have default field the fault value<br>[115:12] the full data<br>[115:14] the time limit<br>[115:18] remains.<br>[115:22] So if I start this in question one<br>[115:35] there is no timer happening.<br>[115:44] Um,<br>[115:49] okay. Let's see what happens if I start<br>[115:52] the time limit instead of minus one<br>[115:58] to um I don't know maybe 20.<br>[116:06] Let's analyze this. If I define the<br>[116:09] default, my<br>[116:12] expectation is that the timer<br>[116:16] continues<br>[116:19] with the same value even if I navigate<br>[116:22] to a new page. This is my expectation<br>[116:24] here.<br>[116:26] So, let's see if that's true.<br>[116:31] I'm going to reset quiz<br>[116:36] time limit minus one.<br>[116:44] This is not correct.<br>[116:48] Okay. Because I have changed the build.<br>[116:52] I need to change this one.<br>[116:56] Okay.<br>[116:59] Fire reset<br>[117:02] and let me<br>[117:05] ah yeah you can see 20 19.<br>[117:13] Okay. So this has been<br>[117:20] 11.<br>[117:26] Okay, let's analyze this.<br>[117:31] The first time we had 20 and 20,<br>[117:37] but the second time ah we start from 20<br>[117:41] all the time.<br>[117:44] We start from<br>[117:47] 20 all the time.<br>[118:00] We start from 20 all the time<br>[118:04] because I'm not updating this, right?<br>[118:10] Okay, this uh this is a timer that is in<br>[118:13] the state,<br>[118:15] right? It says a timer that is in the<br>[118:17] state. So this is not really affecting<br>[118:20] this.<br>[118:24] And every time I start I okay every time<br>[118:27] I start the page I initialize that value<br>[118:30] with<br>[118:33] what happens if I define this as part of<br>[118:38] the context.<br>[118:42] Um,<br>[118:48] let me see. A state timer.<br>[119:00] Okay, I have the context here. So, I<br>[119:02] should be able to instead of setting a<br>[119:05] state timer, I should be able to do<br>[119:07] context timer.<br>[119:10] Context timer. Context timer. Context<br>[119:13] timer. Context timer.<br>[119:18] Okay, let's<br>[119:22] change all the instances of<br>[119:26] state timer with<br>[119:30] cdtx timer which I have here. And then<br>[119:36] in the<br>[119:38] timer text,<br>[119:43] I need to do this.<br>[119:53] I need to do this. Yeah, because I have<br>[119:57] changed this automatically. Okay,<br>[120:00] let's see what happens here. This is<br>[120:04] exploration time.<br>[120:09] 20 19 18 17<br>[120:14] Oh,<br>[120:17] it gets<br>[120:26] okay. It gets<br>[120:30] h because I'm doing h<br>[120:36] limit because I'm doing this.<br>[120:41] If I don't do this,<br>[120:47] I don't do this.<br>[121:00] Okay, if I don't do this<br>[121:06] times up<br>[121:08] because yeah, I need this.<br>[121:17] Okay. Context server time limit.<br>[121:24] Change this to ctx time limit because<br>[121:28] I have in the context I have a time<br>[121:31] limit.<br>[121:34] So I was initializing every time to the<br>[121:37] context in the server and now I'm<br>[121:39] initializing to the context<br>[121:42] in the client which makes sense. So,<br>[121:45] okay, now it should work.<br>[121:52] 18 17<br>[121:54] 16.<br>[122:00] No, this is not working.<br>[122:05] This is not working.<br>[122:07] But this is a good way to<br>[122:10] to explore this and to<br>[122:14] to learn more a bit about this. So let's<br>[122:18] check what we have. We have local<br>[122:21] context which is the same than the one<br>[122:26] we get from here.<br>[122:33] 20 seconds. 20 seconds. If I go to<br>[122:36] question one,<br>[122:38] it starts in 20 seconds. Why?<br>[122:42] Because every time I navigate<br>[122:47] this is<br>[122:55] reset to this value but I thought ah<br>[123:00] because it's a timer and now we have<br>[123:03] time limit.<br>[123:07] Okay. So let's h continue with our<br>[123:09] exploration.<br>[123:11] What I'm going to do is<br>[123:16] instead of<br>[123:21] so timer<br>[123:24] what is timer<br>[123:27] define it's in the server timer<br>[123:39] is minus one. Okay. So, what I'm going<br>[123:42] to say is<br>[123:57] what I'm going to say is<br>[124:03] if<br>[124:08] CDX timer<br>[124:12] is<br>[124:15] um<br>[124:17] different that minus one<br>[124:25] then get whatever you have in CTX timer.<br>[124:29] If not then get reset to the original<br>[124:34] value.<br>[124:50] So here<br>[125:03] reset quiz.<br>[125:08] Right now in the context<br>[125:19] uh because it's not CTX timer is<br>[125:25] state timer. So<br>[125:28] if state timer or maybe what I can do is<br>[125:35] find this also in the context<br>[125:51] 20 seconds. If I go to question one 17.<br>[125:55] Yay. And if I go to question three,<br>[126:01] 9 seconds. Yay, we got it.<br>[126:07] Okay,<br>[126:10] so<br>[126:23] yeah, we have this<br>[126:26] context server which is the value of the<br>[126:30] attribute that it changes on different<br>[126:33] pages.<br>[126:38] This is the default value of the<br>[126:39] attribute. This is the custom one that<br>[126:41] we have set via the<br>[126:47] spectral control<br>[126:50] and this is the custom value. Then we<br>[126:52] have the local<br>[126:54] the value in the client that it doesn't<br>[126:58] change<br>[127:00] unless we update it manually.<br>[127:10] And then we have the timer.<br>[127:15] As you can see,<br>[127:18] we have set something like okay, if<br>[127:20] timer is different that minus one, set<br>[127:24] it to the time limit value.<br>[127:29] Then every time I change the page, I<br>[127:33] update it to the previous value. So the<br>[127:35] timer just continues.<br>[127:45] So,<br>[127:53] I don't really need this because I guess<br>[127:56] I can just<br>[127:59] define this as um<br>[128:07] a value that doesn't get properties from<br>[128:10] the server. So, this is just an<br>[128:12] exploration,<br>[128:14] but this I going to<br>[128:17] um<br>[128:23] minus one.<br>[128:34] Okay,<br>[128:37] this is uh reset to 20 because here I<br>[128:43] want it to be minus one.<br>[128:46] So now what I want to do is<br>[128:52] times up.<br>[128:55] This gets gets reset to the<br>[128:59] time limit of this page<br>[129:01] of this the block on this page.<br>[129:08] And this has a different value.<br>[129:20] Stick timer. Stick timer.<br>[129:26] Um, I think I need to reset the quiz.<br>[129:36] Times up.<br>[129:38] Question one 22.<br>[129:47] I think the values are too similar. So,<br>[129:50] let me<br>[129:53] post question three.<br>[129:55] Yeah, because I was really in the quiz.<br>[129:59] So, I want to go to question three,<br>[130:04] exit code editor.<br>[130:08] And here I want to<br>[130:15] to<br>[130:17] maybe<br>[130:26] saving. And if we go to the homepage,<br>[130:36] if we go to the homepage<br>[130:39] and and we have here the vector<br>[130:55] Question one<br>[130:57] 22.<br>[131:00] We can see that from the server we are<br>[131:03] getting for slack question one we are<br>[131:07] getting time limit 22<br>[131:11] that is set to time limit.<br>[131:17] If we go to question two,<br>[131:24] we can see the time limit and this timer<br>[131:28] has been set. And the state here, the<br>[131:31] local state is the one.<br>[131:38] Okay, let me see if we can.<br>[131:44] We go to question one.<br>[131:48] The state here target.<br>[132:01] Okay, this is the value that is being<br>[132:04] updated.<br>[132:10] So now what I want to do is to remove<br>[132:14] this text whenever we are in the<br>[132:15] homepage.<br>[132:22] This is not working.<br>[132:25] I don't know why because state timer<br>[132:30] is less than zero.<br>[132:35] So let's do some debug. If I go to<br>[132:38] sources,<br>[132:40] go to view and we go to here state<br>[132:43] timer.<br>[132:47] I reload the page.<br>[132:50] State timer<br>[133:00] is minus one. So this returns empty.<br>[133:08] Now start timer is zero. Why is zero?<br>[133:15] Why is this hero<br>[133:28] timer minus one<br>[133:33] when this is set to zero? Is there any<br>[133:37] zero here?<br>[133:46] Ah, state timer zero.<br>[133:52] So that's why.<br>[133:56] Okay, let me see.<br>[134:11] Don't need to do so start new timer<br>[134:15] time limit.<br>[134:21] I was<br>[134:26] I just can't remove this.<br>[134:45] Um yeah, it's uh triggering this every<br>[134:49] time I go through this<br>[134:53] variable because it gets updated every<br>[134:56] time a state timer is updated as well.<br>[134:59] So I'm just going to<br>[135:03] reset quiz.<br>[135:05] I don't get that value because state<br>[135:08] quiz is minus one. But then on every<br>[135:11] question I can show the remaining time<br>[135:17] and what I want to display is that the<br>[135:21] time is up.<br>[135:27] Yep.<br>[135:28] But in the reset quiz, this shouldn't be<br>[135:31] displayed.<br>[135:35] Nice. Nice. Nice.<br>[135:41] Let's do some more fine tuning.<br>[135:49] Post<br>[135:50] one.<br>[136:12] Okay. So<br>[136:18] right now the content that I'm getting<br>[136:21] is directly what I want to do is<br>[136:26] well we can let's do one test. I can see<br>[136:29] how whatever I put here<br>[136:33] is not retrieved by the root region<br>[136:37] because the root region is this area<br>[136:39] here.<br>[136:46] This is nice actually because<br>[136:49] with block bindings, what I could do is<br>[136:53] to create here a<br>[136:56] section to edit any internal information<br>[137:00] via me meta data for this post. And that<br>[137:06] information is not going to be<br>[137:10] um displayed by<br>[137:13] by the let's check this.<br>[137:23] I have this and<br>[137:32] I'm going to this side. Okay.<br>[137:41] Okay, I want question one<br>[137:44] happens. Okay, question one.<br>[137:49] Yeah, we can see how all the information<br>[137:52] that was outside of the region is not<br>[137:56] displayed here.<br>[137:58] So, I can actually do that.<br>[138:02] And here I have<br>[138:04] interactive logs. So here I can do some<br>[138:09] interactive magic.<br>[138:14] For example, this is an image that uses<br>[138:18] the<br>[138:21] activity API for this light box effect.<br>[138:30] Nice.<br>[138:38] So what I want to display now is I will<br>[138:42] just to display the the number of the<br>[138:46] question.<br>[138:54] The number of the question.<br>[139:01] No, the see the the number or the name<br>[139:04] of the question.<br>[139:06] I can do that here in the render. Maybe<br>[139:09] I can<br>[139:13] one thing that I would like to do is to<br>[139:19] separate this maybe<br>[139:23] a different file and then include it.<br>[139:30] Okay, that's something to explore for<br>[139:32] now.<br>[139:34] What I want to do is to this is the<br>[139:38] content and maybe we can do here an H2<br>[139:47] and<br>[139:49] H2<br>[139:56] with um data wp text current slack. Um<br>[140:03] I'm going to create<br>[140:06] a derived state called title quest<br>[140:11] and in view.js I'm going to say<br>[140:34] Don't I have the question text<br>[140:41] for example here?<br>[140:45] Uh I'm just doing item SL.<br>[140:51] Okay, let's create<br>[140:55] title question or<br>[140:59] question text.<br>[141:02] No, title question is a good one.<br>[141:14] So in the context like let's see what<br>[141:17] information do I have in the context.<br>[141:23] If I go to question two.<br>[141:28] Yeah, because Okay, let's um<br>[141:31] for now title question is going to be<br>[141:35] just this. And I'm going to<br>[141:38] like this for now.<br>[141:50] The question is going to be just an<br>[141:53] empty<br>[141:55] string.<br>[141:57] If I go to question two, let's see the<br>[142:00] information that I have<br>[142:03] in the context. What I have is the<br>[142:12] current slack<br>[142:16] and in the<br>[142:20] state<br>[142:26] I have the slacks here. So with current<br>[142:31] slack<br>[142:35] um<br>[142:39] well ideally<br>[142:42] this is something that um<br>[142:47] this is something that it would be great<br>[142:48] to implement to add some meta data for<br>[142:52] the post and including some information<br>[142:55] like the title and I don't<br>[142:59] something else maybe some documentation<br>[143:02] to to know more about that but yeah I<br>[143:05] think that the the project I'm going to<br>[143:09] remove uh well what I can do<br>[143:13] what I can do is to<br>[143:20] get the slack from the<br>[143:26] current slack<br>[143:30] from the context.<br>[143:35] So what I can do is to<br>[143:40] to a const CTX<br>[143:48] constant slack<br>[143:54] and we can do this<br>[143:59] or yeah let's do this for<br>[144:23] Um,<br>[144:32] Okay,<br>[144:34] so this is the current context that gets<br>[144:38] updated on every new page.<br>[144:51] Let me try something.<br>[145:15] Um, no, this is<br>[145:19] correct because<br>[145:23] t state title question<br>[145:28] and title question.<br>[145:33] I get access to the context which<br>[145:37] contains the<br>[145:41] the current slack because the current<br>[145:44] slack<br>[145:51] the current slack<br>[145:54] is providing is provided here<br>[146:00] and in the view I'm just Then<br>[146:04] uh because maybe there's um<br>[146:09] slash of something<br>[146:13] is or maybe the directives is not is not<br>[146:16] correct is data<br>[146:20] bit text.<br>[146:24] No, it's correct.<br>[146:27] H2 H2<br>[146:36] Let me see here what's happening.<br>[146:40] Um,<br>[146:47] let me see if I go to the build<br>[146:50] and to the render.<br>[146:56] The H2 is there.<br>[147:08] Um, let me do else.<br>[147:26] Okay. So,<br>[147:31] let's debuck this a little bit. What's<br>[147:33] happening here?<br>[147:39] Okay, I don't care about this. But in<br>[147:42] question two,<br>[147:46] in question four,<br>[147:52] uh<br>[147:55] this is not<br>[148:10] Stay timer.<br>[148:27] Okay, this is not triggered.<br>[148:35] uh because I need to access<br>[148:39] not get context but get server context<br>[148:47] and I can directly destructure this<br>[149:03] Okay.<br>[149:05] So, I reset<br>[149:09] and if I go to question two,<br>[149:12] let's see what's happening here.<br>[149:17] Okay.<br>[149:35] What is this luck<br>[149:38] from contact server?<br>[149:51] Okay, this quiz that's fine. But if I go<br>[149:54] to question three,<br>[149:58] why is quiz? Because get server context.<br>[150:04] Get server context.<br>[150:16] Get server context. At this point, it<br>[150:20] should<br>[150:40] ser context at this point. It should<br>[150:43] provide. Okay. If I watch<br>[150:52] Um<br>[150:59] server context.<br>[151:05] Okay, let's get this<br>[151:33] Okay. I don't understand this.<br>[151:46] Okay. Reset quiz.<br>[151:51] quiz<br>[151:54] because server context<br>[151:58] server context current slack is quiz if<br>[152:01] I go to question one.<br>[152:06] Okay, the console still<br>[152:09] has not displayed.<br>[152:16] So at this point,<br>[152:31] this<br>[152:59] So in the context server the Slack is<br>[153:03] question one but this is not displayed<br>[153:10] yet.<br>[153:19] title question.<br>[153:21] Okay,<br>[153:24] I know what's going on. I need to do<br>[153:31] the slack get server context.<br>[153:34] Okay,<br>[153:36] and I'm going to return<br>[153:40] for That's fine for now.<br>[153:51] But in the in it question,<br>[153:54] I get<br>[153:57] subscribed to the context server.<br>[154:01] So what I'm going to do is cdx<br>[154:06] the slack.<br>[154:10] No. Put in the slack.<br>[154:13] Yes.<br>[154:14] CTX. Put on the slack.<br>[154:22] Ah, this is down here in start timer.<br>[154:31] Okay. In that case,<br>[154:36] I don't need to do this<br>[154:39] because whenever the timer starts,<br>[154:44] well, this is not the best place to do<br>[154:46] this, but for now, whenever the timer<br>[154:49] starts, the<br>[155:00] I know this is an internal<br>[155:05] the slug.<br>[155:07] So I can do this. I can do this<br>[155:11] contact server<br>[155:14] init question<br>[155:17] and I'm initializing this here.<br>[155:36] And um okay. And now<br>[155:41] the<br>[155:49] Yeah.<br>[155:52] Yeah. I need to do this.<br>[155:55] I get subscribed to the local that is<br>[155:58] going to be<br>[156:01] set two.<br>[156:04] Okay.<br>[156:05] three.<br>[156:08] And if I remove this<br>[156:17] okay<br>[156:20] and okay, perfect. So, this is what I<br>[156:22] wanted to get. And I think, guys,<br>[156:26] I'm going to stop here.<br>[156:30] Um,<br>[156:32] yeah, I'm very happy with this demo. I<br>[156:35] may<br>[156:37] make it bigger with a better design and<br>[156:40] with more questions and maybe with<br>[156:44] meta data that I can add to the<br>[156:49] to the post. Maybe even create a custom<br>[156:52] post type for the<br>[156:54] questions.<br>[156:57] And<br>[157:01] and yeah, this can be like a nice demo<br>[157:03] of the interactivity routter<br>[157:08] and something that works uh really well.<br>[157:12] I think it's pretty fast the way it<br>[157:14] works.<br>[157:18] We can also do a preload preetch. This<br>[157:23] is something that I want to investigate.<br>[157:25] So every time I go to a question<br>[157:29] um<br>[157:32] it's already loaded.<br>[157:37] So this can also be implemented. So yeah<br>[157:40] I'm going to<br>[157:43] what I'm going to do is to prepare maybe<br>[157:44] 20 questions 30 questions with the meta<br>[157:48] data pointing to the specific<br>[157:50] documentation sites. It will display a<br>[157:52] selection of five with this behavior.<br>[157:55] Each question will have specific time to<br>[157:58] answer the question. It can have images,<br>[158:02] uh code blocks and a lot of things. It<br>[158:05] will be a yes or no. And what else? Um<br>[158:14] and yeah, it will will have a prefetch.<br>[158:17] So the navigation is uh bigger and at<br>[158:20] the end you will get a result. Whenever<br>[158:24] all the questions as whenever all the<br>[158:26] questions have been solved<br>[158:30] you can get a<br>[158:33] button here to check results.<br>[158:38] If I reset quiz, I do start question one<br>[158:43] have some time. But if I navigate before<br>[158:48] I can get the time I have spent on each<br>[158:51] question<br>[158:54] and by the end I can get a a result.<br>[158:57] Okay. Yeah, I like it. I like it. This<br>[158:59] is a good use case for this. Okay guys,<br>[159:02] hope you have a great weekend and hope<br>[159:05] this session has been useful.<br>[159:08] Um,<br>[159:10] and yeah, see you<br>[159:13] next week or any other week. Okay, bye<br>[159:17] guys.
<!-- deep-read:sections end -->