Question presented to candidate:
"Our form inputs need unique ids so <label for> and aria-describedby work. Someone built them from getCurrentInstance().uid, and since we added SSR we get hydration warnings. What does useId() in Vue 3.5 do differently, and how would you fix this?"
What a strong answer should cover:
useId()(Vue 3.5) returns an id that is unique per app and identical on server and client, because it is derived from the component's position in the tree, not from a global counter.getCurrentInstance().uidis a module-level counter of every instance ever created; on a server it keeps growing across requests, so the server and the fresh client disagree, causing hydration mismatches.getCurrentInstance()is an internal-leaning API that the docs discourage in application code.app.config.idPrefixchanges thevprefix, useful when several Vue apps share a page.useId()must be called in setup; each call in the same component gives the next id; async boundaries get their own segment so ids stay stable.- Derive sub-ids from one call (
${id}-hint) rather than calling it many times; never useMath.random()orDate.now()for ids in SSR.
Clarifying questions expected:
- "Is there more than one Vue app mounted on the page, for example micro-frontends?"
- "Are we on Vue 3.5 or later? Before that, Nuxt's
useIdor a provide-based counter was the workaround."
Code / implementation expected: Yes — a field component using useId(), ideally shown through SSR and hydration.