Event Replay
This feature is experimental and off by default. Its behaviour and configuration may change in a future release.
What it does
Archibald hydrates interactive components ("islands") progressively, so there is a short window between the server-rendered HTML becoming visible and the island's JavaScript taking over. Interactions a user makes during that window would normally be lost.
With Event Replay enabled, those pre-hydration interactions are buffered and re-applied to the component once it has hydrated, so the user's early input is not dropped.
{
"experimental": {
"eventReplay": true
}
}
Supported interactions
While an island is still un-hydrated, the following interactions are captured and replayed after it hydrates:
| Interaction | Captured | Replayed as |
|---|---|---|
| Click | Click on any element inside the island | Click on the nearest activatable element |
| Keyboard activation | Enter / Space on a focusable element | The same activation |
| Typing | Latest value of input, textarea and contentEditable fields (with caret position) | Value re-applied so controlled inputs keep it |
| Checkbox / radio | Final checked state | The toggle |
| Select | Selected option | The change |
| Form submit | A submit attempt | The submit |
| Focus | The last-focused element | Focus (and caret) restored last |
Interactions are replayed in the order they happened, with focus restored at the end to preserve typing continuity.
Replaying every keystroke
Typing is collapsed to the final value per field: the buffer stays proportional to the number of fields, and the replay restores the value the user ended up with — which is what an effect on that value reacts to. A handler that counts or accumulates per character (a remaining-characters counter, a per-keystroke analytics event) sees a single jump instead of each keystroke.
Turn on experimental.replayKeystrokes to keep every keystroke instead:
{
"experimental": {
"eventReplay": true,
"replayKeystrokes": true
}
}
The kept keystrokes replay in the order they were typed, but within a single tick and without their original spacing — so behaviour that depends on the timing between characters (debounce windows, a request per character) still differs from live typing. It also grows the buffer with the number of keystrokes rather than the number of fields, which is why it is off by default.
How it works
- A small inline script records interactions on elements still marked as not-yet-hydrated. Discrete activations (clicks, keyboard activation, submits) are prevented from triggering their default behaviour until the island is ready; typing and value changes are left untouched so the user still sees their input.
- Once the island hydrates, the buffered interactions are replayed through the (now hydrated) component and the recorder listeners are removed.
- Islands streamed in or inserted after the initial page load are picked up automatically.
The recorder only runs when eventReplay is enabled. When it is off, no interactions are captured or replayed.