Skip to main content

Event Replay

warning

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:

InteractionCapturedReplayed as
ClickClick on any element inside the islandClick on the nearest activatable element
Keyboard activationEnter / Space on a focusable elementThe same activation
TypingLatest value of input, textarea and contentEditable fields (with caret position)Value re-applied so controlled inputs keep it
Checkbox / radioFinal checked stateThe toggle
SelectSelected optionThe change
Form submitA submit attemptThe submit
FocusThe last-focused elementFocus (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.
info

The recorder only runs when eventReplay is enabled. When it is off, no interactions are captured or replayed.