HP5003 (focus-lost) means the element that had focus, or the text selected
in it, was lost while the page hydrated. A user who started typing before the
page was ready suddenly types into nothing. Avoid re-creating the focused
element during hydration, and do not move focus in effects that run on load.
| Code | HP5003 |
|---|---|
| Name | focus-lost |
| Default severity | Warning |
| Group | Interaction during hydration |
| What it means | The focused element or the text selection was lost during hydration. |
What the HP5003 focus lost finding means
The finding comes from the interaction checks
(checks.interactions: true or --interactions). With the page's scripts
held back, hydration-proof focuses the first text field and selects text in
it, then lets the page hydrate and checks both again:
The text field that had focus before hydration lost it while the page hydrated.
The text selection in the field changed from 0-5 to 0-0 while the page hydrated.Losing focus is reported with higher confidence than a changed selection. Both are warnings.
Likely causes
- A hydration mismatch around the field: React throws away that branch and renders a new field, which has no focus. Look for HP1010 on the same page.
- An effect that calls
focus()on another element when the page loads, such as a search box or a dialog. - A value set on the field during hydration, which resets the selection (see HP5002).
How to fix it
Avoid re-creating the focused element during hydration (fix mismatches around it), and do not move focus in effects that run on load.
- Fix the hydration findings on the same page first; a replaced branch is the most common cause.
- Move focus only in response to a user action, or only when nothing else has focus yet:
"use client";
import { useEffect, useRef } from "react";
export function SearchBox() {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
// Before: inputRef.current?.focus() took focus from the field in use
if (document.activeElement === document.body) {
inputRef.current?.focus({ preventScroll: true });
}
}, []);
return <input ref={inputRef} type="search" name="q" />;
}When it is acceptable
If the page moves focus on purpose (a dialog that opens on load), ignore
code: "HP5003" for that route with a reason; see
ignoring findings.