You register a button listener, then register it again with once enabled. Why does it still run on a second activation? The second call can match an existing listener rather than replace its configuration. Looking only at the newest options object gives the wrong account.
The short answer is to track the target, event type, callback identity and capture flag. For an existing matching registration, another addEventListener call does not overwrite its once or passive settings. To deliberately change that registration, remove the matching listener and add the intended replacement, while considering order and component lifetime.
This lesson uses original, harmless event ledgers for fictional website components. It separates function identity from similar-looking source code, registration options from callback state, and cleanup from the code already running. The examples explain the standard's model; they are not a browser compatibility certificate or a reason to intercept ordinary controls unnecessarily.
This specialist guide belongs to the Websites root. It also connects to The Gold Standard of Education | Learning That Transfers into Life and the How X Works hub. The worked cases are original teaching examples; their numbers are stipulated so that the reasoning can be checked.
eduKateSG · Websites
Find your next learning step
Record the accepted listener before reading the newest options. Predict repeated dispatch and cleanup from object identity and the registration lifetime.
ROUTE 1 · CHAPTERS 1–3
Identify the registration
Name the component lifetime, callback object and matching key.
ROUTE 2 · CHAPTERS 4–6
Trace duplicate options
Work both once-setting orders and an intentional replacement.
ROUTE 3 · CHAPTERS 7–10
Keep identities distinct
Compare capture, option objects, wrappers, bound functions and listener objects.
ROUTE 4 · CHAPTERS 11–15
Follow dispatch and cleanup
Trace order changes, removal, once timing, passive policy and signal ownership.
ROUTE 5 · CHAPTERS 16–18
Practise and retain evidence
Reconstruct mount lifetimes and check deliberate replacements.
Chapter contents
Identify the registration · Chapters 1–3
1. Start with the behaviour the visitor encounters
Trace duplicate options · Chapters 4–6
4. Work the false-to-true once attempt
Keep identities distinct · Chapters 7–10
7. Match capture during cleanup
8. Distinguish callback identity from the options object’s identity
Follow dispatch and cleanup · Chapters 11–15
11. Follow the order change caused by remove and readd
12. Understand removal during an invocation sequence
13. Locate once removal before the callback body
14. Keep passive policy separate from listener identity
15. Use a signal for ownership without treating duplicate add as reassignment
Practise and retain evidence · Chapters 16–18
16. Work a changed mount and cleanup sequence
CHAPTER 1 OF 18 · Identify the registration
1. Start with the behaviour the visitor encounters
Imagine a small preview panel with a button that opens supporting information. A component mounts, registers its listener and later changes configuration. The visitor expects one coherent response per action. If old registrations accumulate, one action may unexpectedly run several callbacks or update a closed panel.
The reverse failure is also possible. An engineer believes a second registration changed a listener into a one-time callback, but its original configuration remains. The visible error appears only on the next action, after the first test seemed successful. A single click is therefore a weak test of a once-setting change.
Before reviewing the API, describe the intended lifetime. Should the behaviour remain while the component is mounted? Should it happen only once per component, once per operation or once for the whole page? These are different requirements. The word once in an options object does not define the product's lifetime policy by itself.
For the paper examples, use an EventTarget called panel and an event type called preview. This isolates registration behaviour from DOM ancestors, default browser actions and input-device differences. Later chapters add the relevant boundaries without pretending the simple target reproduces an entire accessible button journey.
The first evidence question is modest: which registrations exist immediately before dispatch? Answer that from the actual add and remove history. Then explain what a dispatched event can invoke. A screenshot of the latest code line cannot reconstruct registrations that earlier lines already created.
CHAPTER 2 OF 18 · Identify the registration
2. Give each callback a persistent identity
Let function F increment a counter. Register F for preview, then register F again for preview with the same capture value. Both calls refer to the same function object. Under the listener identity rule, the second call does not create a second matching registration.
Now write two separate arrow-function expressions that each increment the same counter. Although their bodies look identical, evaluating those expressions creates different function objects. Call them F1 and F2. Registering both can produce two separate listeners because the callbacks differ in identity.
This distinction is about objects, not spelling. A variable can be renamed while still pointing to F. Conversely, the same source expression evaluated during two component mounts can produce two different closures. A familiar-looking line in a repeated setup function does not prove that it reused the first callback.
For a ledger, assign callbacks labels when they are created. At setup step one, create F1. At a later setup step, create F2. Keep those labels even if both functions came from the same source line. This exposes registration accumulation that a source-only comparison can miss.
The visitor sees the consequence as duplicate work, but the repair begins with lifetime and identity. Retain the callback reference that cleanup needs, or use a deliberately designed lifecycle mechanism. Do not assume a newly written anonymous function describes the identity of the earlier anonymous function merely because its text is identical.
CHAPTER 3 OF 18 · Identify the registration
3. Define the matching key without including every option
Within a target's listener list, matching registration uses the event type, callback identity and capture value. The target matters because different objects have different listener lists. Registering F on panel and F on a separate control does not place both registrations in one shared global bucket.
Call the conceptual key K = target, type, callback, capture. This is a teaching notation rather than a JavaScript array the browser must store. It makes the relevant comparison explicit. Once, passive and signal are additional registration options, but they do not all become extra dimensions of this duplicate-matching key.
Suppose K already exists with once false. A later add call supplies the same K and once true. The presence of the newer true value does not imply the existing registration was rewritten. Reconstruct the accepted registration, not a fictional merge of all options ever supplied.
Change capture while retaining target, type and callback. That produces a different key. The distinction will matter both when adding and removing listeners. Treating capture as merely another ignored option would make the identity model wrong in the opposite direction.
For an initial review, fill one row per accepted registration and record its options at creation. On a duplicate add, annotate the attempted call separately. This preserves the difference between a request made by code and the listener state that resulted. The same evidence habit helps with other APIs where a repeated call is not an update operation.
Event type strings also belong to the key. The names preview and Preview are different strings; registering one does not subscribe to the other. Keep the actual dispatched type in the ledger rather than assuming that similarly capitalised labels identify the same event.
Begin with a new target and a retained function F. The first call registers F for preview with once false and capture false. A second call supplies the same type, F and capture false, but now once true. There is still one matching registration with its original once false setting.
Dispatch a fresh preview event twice. In the simple target model, F runs on both dispatches. Its total counter becomes two. The second add call neither doubled the listener count nor changed the original listener into a one-time registration.
Two incorrect explanations can therefore produce different predictions. One says that every add call always adds a callback, predicting four invocations across two dispatches. Another says the latest options replace the first, predicting one invocation. The actual identity-and-creation account predicts two.
The example is useful precisely because the first dispatch alone cannot distinguish every theory. A single registration that stays active and one that removes itself after its first invocation both run once initially. The second dispatch exposes the lifetime difference.
Keep each dispatched Event object separate in the exercise. Reusing an event while it is already being dispatched introduces another rule that this baseline does not need. The ledger's purpose is to isolate the configuration attempt, so the event sequence is deliberately simple and repeatable.
Take another fresh target. This time the first accepted registration uses once true. A duplicate add supplies once false with the same target, type, callback and capture. The original one-time registration remains; the later false value does not make it permanent.
Dispatch twice. The first dispatch invokes F under the once registration and removes that registration as part of invocation. The second dispatch finds no such registration, so the counter remains one. This is the reverse of the previous example, despite the most recent options objects looking opposite.
The pair of examples explains why reading only the final addEventListener call is insufficient. In one case the latest line says true but the listener persists. In the other it says false but the listener is one-time. The accepted creation history supplies the missing context.
Do not summarise the lesson as “once does not work.” It works according to the registration that was actually accepted. The error is treating a duplicate registration attempt as though it were an option-update method. Naming that error points towards a specific repair.
For a learner, give the two add calls without announcing which is first, then require a chronological reconstruction. They should identify the accepted options, predict two dispatch outcomes and explain why swapping the call order changes the result. That checks the mechanism rather than memorising a preferred code snippet.
CHAPTER 6 OF 18 · Trace duplicate options
6. Change configuration through an explicit lifecycle
Suppose the intended behaviour really changes from persistent to one-time. Remove the existing listener using its matching type, callback and capture, then add the intended new registration. In our simple baseline, there is no matching registration left to block the new one.
The new registration now owns its supplied once setting. Dispatch twice and the intended one-time behaviour can be observed. This is a deliberate remove-and-create sequence rather than an assumption that another add call mutated the existing record.
The sequence also has consequences beyond the setting. A removed and readded listener can occupy a different position relative to other listeners on that target. If callback order matters to the application, the replacement needs an order check as well as an invocation-count check.
An actual component should make configuration changes at a well-defined lifecycle boundary. Repeatedly removing and adding listeners during unrelated rendering can introduce confusing order changes or intervals without the intended behaviour. The right design depends on the task; this article does not prescribe a framework-specific pattern.
Use a small evidence record: the prior accepted registration, matching removal, new accepted registration and dispatch outcomes. That record lets a reviewer distinguish a real configuration replacement from a duplicate request. It also makes clear which other registrations were preserved rather than assuming cleanup erased every callback associated with the event type.
Register F for preview with capture true. Then try to remove F using capture false. The removal request does not match that registration's capture value, so it does not remove the capture-true listener. Similar callback and type information are not enough when one part of the key differs.
Now remove with capture true. The matching registration can be removed. In the paper ledger, mark the accepted key explicitly on both the add and remove rows. This catches a quiet mismatch that can otherwise look like a failed cleanup method.
The capture option is related to event propagation in a DOM tree, but its identity role can be stated independently. A complete DOM example also needs a path, target and event phases. Do not infer ancestor propagation behaviour from a plain EventTarget that has no DOM parent chain.
Registering F separately with capture false and capture true creates two distinct registrations on the same target. Removing one capture variant does not automatically remove the other. A cleanup routine must match the registrations it actually owns.
For a component review, write capture deliberately rather than relying on a vague memory of whether the original call used an options object or a boolean. Those surface forms can express the same effective capture value. The actual matching value, not the syntax style, determines whether cleanup addresses the intended registration.
CHAPTER 8 OF 18 · Keep identities distinct
8. Distinguish callback identity from the options object’s identity
The options object used in an add call is not itself the callback identity. Two different options objects can express the same capture value and attempt to register the same callback. That does not create two registrations merely because the option objects have different object identities.
Conversely, mutating an ordinary options object after registration does not mean the browser's accepted listener record continually rereads it. The call processes the supplied values. A later property assignment to that JavaScript object is not an event-listener configuration API.
For an original exercise, create options O with once false, add F using O, then assign O.once = true without another accepted registration. Predicting one-time behaviour would treat O as a live control panel when the setup did not establish that relationship.
This differs from a callback that deliberately reads a mutable application object each time it runs. In that case changing the object can change what the callback does, while the listener's once and capture configuration remains the same. Callback logic and registration policy are separate layers.
A useful review labels which values were read during setup and which are read during invocation. Otherwise a true statement about live application state can be misapplied to captured registration settings. The question is not whether objects can mutate; it is which operation observes that mutation and at what time.
CHAPTER 9 OF 18 · Keep identities distinct
9. Keep bound functions and wrappers in the identity ledger
Calling a function's bind method creates a bound function object. If setup registers one bound function and cleanup calls bind again to produce another, cleanup has a different callback reference. The fact that both use the same original function and receiver does not make them identical objects.
Call the first bound function B1 and the second B2. Register B1. A removal request naming B2 does not match B1. The listener can remain, producing activity after the component owner thought it had completed cleanup.
The same issue appears with wrappers. Registering an arrow function that calls handlePreview does not register handlePreview itself. Removing handlePreview later addresses a different callback identity. Store or otherwise manage the wrapper's actual identity if that is the callback chosen for registration.
For a learner, draw a small object map: original function F, bound function B1, separately created bound function B2 and a wrapper W. Mark which one was passed to add. The map explains the cleanup mismatch without requiring a large application or a mysterious browser leak.
Do not turn the lesson into a blanket ban on wrappers or bound methods. They can serve a legitimate purpose. The requirement is to maintain an ownership and cleanup account that matches the function actually registered. A convenient callback expression still needs a lifecycle when its target can outlive the component that created it.
CHAPTER 10 OF 18 · Keep identities distinct
10. Separate a listener object from its current method
An event listener can also be an object with a handleEvent method. Its object identity is distinct from the function currently stored in that method. Registering the same listener object again is not equivalent to registering a newly created object with an identically written method.
For a conceptual case, register object L. Its handleEvent method records old. Later replace that method with another function that records new. The listener object remains L. The callback invocation mechanism can use its current handleEvent operation without the registration itself being replaced.
This is a useful contrast with mutating an options object. Both involve JavaScript objects, but the API consults them at different stages and for different purposes. A rule that says all objects are frozen at registration would misdescribe the listener object; a rule that says every option is live would misdescribe configuration.
Cleanup should still use the registered listener object L rather than a newly constructed lookalike. If the application deliberately swaps whole listener objects, give them separate labels and account for removal of the old registration. Similar methods do not merge identities.
Use this branch only when it makes the component clearer. A student does not need listener objects to understand the basic duplicate rule. The example extends the same identity discipline into another callback representation and tests whether the learner can distinguish registration identity from the code executed through that identity.
CHAPTER 11 OF 18 · Follow dispatch and cleanup
11. Follow the order change caused by remove and readd
Begin with two accepted registrations for one type and capture setting: F then G. In the simple baseline their callbacks are considered in that registration order. A duplicate add of F does not move it to the end merely because its call appears later in the source trace.
Now remove F and add it again. The accepted list becomes G then the new F registration. This is a real lifecycle change, so an invocation-order difference can occur even when the same function object is reused. Replacing options through removal is not necessarily order-neutral.
Give F and G harmless log messages rather than side effects. The first baseline dispatch logs F then G. After remove-and-readd, the changed ledger logs G then F under the stated simple conditions. Keep event phases and stop behaviour fixed so they do not obscure the registration question.
If an application relies on F setting state that G reads, this order change can be consequential. That dependency deserves an explicit design rather than an accidental arrangement of setup calls. The listener API does not know which callback the author considers conceptually first.
The practical check is to observe both counts and sequence when replacing a registration. A test asserting only that each callback ran once could miss a changed relationship between them. The correct scope of the test follows the application's actual dependency, not the smallest assertion that happens to pass.
CHAPTER 12 OF 18 · Follow dispatch and cleanup
12. Understand removal during an invocation sequence
In the DOM dispatch model, the relevant target's listener list is cloned for an invocation stage, but a listener's removed flag still matters. A callback removed before its turn need not run merely because it appeared in that stage's initial clone.
Take the simple sequence F then G. F's callback removes G before G's turn. Under the stated conditions G is skipped. A mistaken model that treats the clone as a completely independent immutable copy of every registration would predict G still runs.
Removal does not travel backwards in time. If G already ran before another callback removed it, that completed invocation is not undone. It also does not stop the JavaScript body of a callback that is already executing merely because its registration is removed during that body.
Additions have their own timing boundary. A callback added after a particular invocation stage's clone was made is not included in that clone. Avoid broadening this into a claim that no newly added listener can ever run anywhere in the same DOM dispatch: later targets or phases can involve further invocation steps.
Our lesson keeps the baseline at one target and one declared stage when demonstrating this rule. An actual tree trace should record where and when each invocation list is obtained. This makes the result explainable without using the vague phrase that the browser caches all events or rereads everything continuously.
CHAPTER 13 OF 18 · Follow dispatch and cleanup
13. Locate once removal before the callback body
For a once listener, the DOM invocation algorithm removes the registration before calling its callback. This ordering matters for reentrant dispatch. A one-time listener that starts a fresh dispatch from inside its callback is no longer present as that same registration for the nested event.
Create a harmless model in which once callback F logs outer and dispatches one fresh event of the same type. Without any re-registration, the nested event does not invoke that removed once registration again. The once rule is not a cleanup scheduled only after F returns.
Now change the exercise: inside F, deliberately add F again before dispatching the fresh nested event. That is a new registration because the old one was already removed. The new registration can participate in the nested dispatch according to the stated setup. A naive unconditional version can recurse repeatedly, so use an explicit one-shot guard in a local test.
The meaningful boundary is the registration, not a universal promise that a function object can never run again after once was used somewhere. The same callback can be registered later, on another target or with another capture setting. Each accepted registration has its own lifetime.
For learners, stop before writing a complicated recursive demonstration. First predict the old registration's state at callback entry. Then add exactly one new action and trace its effect. The controlled change exposes why once removal timing matters without turning an educational example into an unbounded event loop.
CHAPTER 14 OF 18 · Follow dispatch and cleanup
14. Keep passive policy separate from listener identity
Passive concerns whether the listener can cancel an event's default action through preventDefault. It is not a callback identity field, and it does not mean the callback cannot run, change application state or affect performance. Its actual role needs to be explained through the relevant event and browser context.
For the registration question, the important point is narrower. A duplicate add with a different passive setting does not simply overwrite the accepted registration. If an intentional policy change is required, the registration lifecycle must establish the intended new options rather than rely on a duplicate call.
Some event types and targets have default passive behaviour defined by the platform. Do not generalise the default from a custom preview event to touch or wheel handling on document-related targets. Check the current standard and actual intended environment before interpreting a scrolling result.
Likewise, an event must be cancelable for ordinary preventDefault cancellation to apply. A failed default-prevention attempt can have more than one explanation. It does not automatically prove that an add call updated or failed to update passive settings.
Keep the test focused. Verify the accepted listener configuration through a relevant declared event scenario, while preserving the native interaction and accessibility needs of the task. A registration exercise should not become a reason to block scrolling or keyboard behaviour without a genuine interface requirement.
CHAPTER 15 OF 18 · Follow dispatch and cleanup
15. Use a signal for ownership without treating duplicate add as reassignment
The listener API accepts a signal option for lifecycle-related removal. That can connect a registration to a component's cancellation lifetime. An already-aborted signal prevents the proposed listener from being added under the standard's rules.
However, another add call with the same matching listener key is not a general operation for transferring ownership to a different controller. The duplicate identity rule still matters. If an application needs a new accepted registration with a different lifetime, make the removal and replacement explicit and check the relevant cleanup behaviour.
The companion article on combined abort signals explains signal state, retained reasons and input dependencies. Those concepts help identify which lifetime the component intends to use. They do not replace the separate listener matching rule or make callback references irrelevant during registration review.
For a paper audit, record the signal supplied with the accepted creation, whether it was already aborted, and what later cleanup was actually observed. Keep unsuccessful or duplicate registration attempts separate. This avoids assigning a controller to a listener solely because that controller appeared in the most recent setup line.
An actual implementation should test its chosen lifecycle in the intended runtime. The present lesson deliberately avoids claiming that every duplicate registration pattern or polyfill handles signal-related details identically. Use the standard and documented environment, and favour an ownership design that is explicit enough to inspect rather than dependent on an accidental duplicate call.
CHAPTER 16 OF 18 · Practise and retain evidence
16. Work a changed mount and cleanup sequence
A fictional component mounts twice. The first mount creates wrapper W1 and registers it for preview. The second mount creates W2 with identical source text and registers it. Both use capture false. How many matching registrations exist? Two, because W1 and W2 are different callback objects.
Cleanup then calls removeEventListener with a third newly created wrapper W3. Neither W1 nor W2 matches W3. Under the declared baseline, both original registrations remain. One subsequent preview dispatch can therefore run both, even though the cleanup line visually resembles the setup line.
Repair the trace by retaining W1 and W2 as the identities owned by their respective mounts. Remove each accepted registration with its actual reference and capture value when that lifetime ends. The intended component design might instead prevent the second mount or deliberately reuse one registration; state that policy rather than guessing it from repeated source code.
Now change the case so both setup calls reuse one retained F with capture false. Only one matching registration is accepted. Cleanup with F and capture false removes it. The same two-mount story has a different result because callback creation changed, not because the browser decided duplicates were sometimes allowed at random.
The independent transfer check asks the learner to label callback creation before counting registrations. If they count add lines instead of accepted keys, the two changed cases reveal the mistake. A dependable explanation can reconstruct both without relying on a framework name or a screenshot of the latest render.
CHAPTER 17 OF 18 · Practise and retain evidence
17. Check what remains after a deliberate replacement
Suppose target panel has F and G for preview, both capture false. Remove F with the matching key and add F back with once true. The accepted state is now G followed by a new once registration for F. The first fresh dispatch runs both under the simple baseline, and the second runs only G.
Count registrations and invocations separately. Before the first dispatch there are two registrations. After F's one-time invocation there is one. Across two dispatches G runs twice and F once. A single total count of three would conceal which callback persisted.
Add a capture-true F registration to a fresh version of the problem. The cleanup and one-time replacement of capture-false F do not erase that other identity. A complete DOM trace would need phases to explain its invocation position. The registration ledger alone can still show that two distinct F registrations must not be conflated.
Remove one input from the exercise: if the record does not say which callback object was passed during setup, can cleanup correctness be inferred from a matching function name in a later code listing? Not reliably. The name can refer to a different object by then. Preserve the creation and reference relationship.
These checks identify why a working first interaction is not sufficient evidence of a stable lifecycle. Test repeated interaction, teardown and re-setup under the actual requirements. The purpose is to verify the visitor's ongoing task, not merely demonstrate that an initial callback can print a message.
CHAPTER 18 OF 18 · Practise and retain evidence
18. Keep a reviewable registration record
For each component-owned listener, retain the target, event type, actual callback identity and effective capture value. Record the accepted creation options, the intended lifetime and the cleanup mechanism. Distinguish those accepted registrations from duplicate add attempts and removal attempts that did not match.
Use small local tests for the claims the component makes. Two dispatches check a once policy better than one. Repeated setup checks callback accumulation. Teardown followed by dispatch checks remaining activity. A controlled order trace checks whether remove-and-readd changed a dependency between callbacks.
Do not claim a browser or device result from a paper ledger alone. A local runtime can check its supported EventTarget behaviour while leaving DOM propagation, passive defaults, user activation and actual interface accessibility unexamined. State the tested boundary instead of turning one result into a universal compatibility statement.
For repair, begin with one retained callback and one event type. Stabilise by changing only once and predicting accepted state. Extend with wrappers, capture variants and a deliberate replacement. Require the learner to identify what stays the same and which change creates a new matching key.
Continue through the Websites root for the complete user journey, the abort-signal guide for cancellation lifetimes and the observer guides for other callback timing problems. Their common habit is a precise history of objects and state. Their API rules remain different, so carry the habit across without copying a mechanism that does not apply.
Continue through the verified reading route
Combine cancellation reasons deliberately
Combine cancellation reasons deliberately. Keep signal state and component lifetime separate from listener identity.
Trace records after a component leaves its container
Trace records after a component leaves its container. Compare another lifecycle problem while preserving the different rules for observers and aborting activities.
Separate recorded attributes from callback-time state
Separate recorded attributes from callback-time state. Practise keeping a recorded field and a live object distinct; do not transfer observer queue rules to AbortSignal.
Separate requestSubmit from submit in the form submission lifecycle. Continue with the native form lifecycle when the callback under review is a submit handler. Correct registration does not establish which method entered validation, whether the event was reached or whether native continuation was canceled.
Copied structure and instance behaviour
When a copied control looks complete but responds differently, follow separating cloned markup from registered event listeners. The practice-card traces distinguish new node identities, target-owned registrations, delegation, captured references and instance setup.
Connected practical checks
The Gold Standard of Websites | Retaining an Event’s Current Target Before Deferred Work Runs
The Gold Standard of Websites | Retaining an Event’s Current Target Before Deferred Work Runs. Continue from listener registration options into the lifetime of currentTarget and retained invocation inputs.
Frequently asked questions
Does every add call create another listener?
No. The matching target, type, callback identity and capture value determine whether another matching registration is accepted. Two freshly created wrappers can be different callbacks even when their source text is identical.
Does the latest once value win?
A duplicate add is not an option-update operation. The original accepted registration retains its once policy. Remove the matching registration and deliberately create its replacement if the intended policy changes, while checking order and lifetime consequences.
Why does cleanup with an identical arrow fail?
A new arrow expression produces a new function object. Similar text does not supply the original callback reference. Retain the identity that was actually registered or use another deliberately designed lifecycle mechanism.
Does removal interrupt a callback already running?
Removing a registration prevents its later participation according to dispatch rules. It does not undo completed work or automatically stop the currently executing JavaScript body. Code already running needs its own state checks where appropriate.
Which checks were actually run?
Eight focused EventTarget checks passed in Node v24.22.1, covering duplicate once settings, wrappers, options mutation, order, removal, listener objects and nested dispatch. They are local runtime checks. No browser-tree propagation, passive-default or device compatibility verification is claimed.
Authoritative sources and further reading
WHATWG DOM Standard: EventTarget and dispatch. Primary registration, removal and invocation algorithms. The ledgers and changed mount examples here are original teaching constructions.
Web IDL Standard: calling a user object’s operation. Primary callback-interface context for invoking listener objects. Keep this separate from the earlier processing of registration options.
Return to the Websites subject guide, The Gold Standard of Education, or the How X Works hub.