In Vue 3.5, what does the data-allow-mismatch attribute do, which values does it accept, and when is it the wrong fix?
answer
- added in 3.5
- silences, does not change behaviour
- five mismatch types
- empty value allows everything
- class stays at the server value
basics
~20 sdata-allow-mismatch (Vue 3.5+) marks a hydration mismatch as expected, so Vue stops reporting it; it does not change how Vue recovers. Values are text, children, class, style or attribute, comma-separated, or empty for all. It is wrong for bugs you can fix.
solid answer
~50 s`data-allow-mismatch` is a plain attribute, added in Vue 3.5, that tells hydration a difference on that element is intentional. It suppresses the dev warning and the production `Hydration completed but contains mismatches.` error for that case, and nothing else: text is still replaced with the client value, wrong nodes are still removed and re-mounted, and class, style and attribute differences stay check-only, meaning the server value can remain in the DOM. The value restricts which kinds are allowed: `text`, `children` (which also covers text), `class`, `style`, `attribute`, or a comma-separated list; an empty value allows every type. It fits inherent, harmless differences such as a locale-formatted date. It is the wrong fix for invalid HTML nesting, random ids, or browser-only state read during render, and especially for class mismatches, where silencing the report leaves a wrong class on screen.
code
vue · 13 lines<script setup lang="ts">
const props = defineProps<{ updatedAt: string }>()
const label = new Date(props.updatedAt).toLocaleString()
</script>
<template>
<p>
Last updated:
<!-- Inherent difference: server and visitor locales differ.
The client value wins; only the warning is silenced. -->
<time :datetime="props.updatedAt" data-allow-mismatch="text">{{ label }}</time>
</p>
</template>go deeper
Recall that the attribute exists from Vue 3.5 and only silences expected hydration mismatches; name its values.
Explain that recovery is unchanged, that children covers text, that an empty value allows everything, and where Vue looks for the attribute per type.
Argue when suppression is acceptable versus a fix, and warn that silencing class, style or attribute mismatches leaves stale values in the DOM.
Set a team policy: every suppression documents the inherent difference it accepts, and blanket attributes on layout roots are rejected in review.
## What the attribute is `data-allow-mismatch` is a special attribute recognised by Vue's hydration code since **Vue 3.5**. It is rendered into the HTML like any other attribute, and during hydration Vue consults it before reporting a mismatch: ```html <span data-allow-mismatch="text">{{ lastSeen.toLocaleString() }}</span> ``` The key point for interviews: it changes **what Vue reports**, not **what Vue does**. ## Accepted values | Value | Allows | |---|---| | *(empty)* | every mismatch type | | `text` | the element's text content differs | | `children` | the element's child nodes differ; also covers `text` | | `class` | the `class` attribute differs | | `style` | the `style` attribute differs | | `attribute` | another known HTML or SVG attribute differs | Several types can be combined with commas, for example `data-allow-mismatch="class,style"`. There is no `all` or `*` keyword: an empty value is the "allow everything" form. ## Where it applies In the Vue 3.5 source the lookup differs by type: - For **text** and **children** mismatches, Vue walks up from the element to the **nearest ancestor that carries the attribute** (the element itself included) and checks that value. - For **class**, **style** and **attribute** mismatches, only the element's **own** attribute counts. - A **node** mismatch (a different element or node type where Vue expected another) is allowed by a `children` permission on the parent side, or by the attribute on the mismatching node or vnode itself. One practical caveat: put the attribute on the element that directly wraps the varying value. In 3.5.43, a bare text node that sits next to sibling elements is compared without consulting the attribute, so text mixed with other elements can still warn. ## What suppression leaves unchanged With or without the attribute, Vue 3.5 recovers the same way: 1. **Text** differences: the DOM text is overwritten with the client value. 2. **Missing or extra children:** missing nodes are mounted, extra server nodes are removed. 3. **Wrong nodes:** the server node is removed and the client vnode is mounted in its place. 4. **Class, style, attribute:** the warning calls these **check-only**; the DOM is not rectified in production, so the element can keep the server's value. The attribute only removes the report, in development and in the production summary error alike. The cost of re-mounting, and the stale class or attribute, remain. ## When it is the right tool - A value whose difference is **inherent and harmless**, and where you prefer the client's version: a timestamp formatted in the visitor's locale, or a "last updated" label. - Third-party or legacy markup you cannot make deterministic, where the client result is acceptable. ## When it is the wrong fix - **Invalid HTML nesting** (`<div>` inside `<p>`): fix the markup; suppression hides a subtree being rebuilt on every load. - **Random or counter ids:** use `useId()` so both sides agree. - **Browser-only state read during render** (window size, `localStorage`, `matchMedia`): defer it past hydration with a `ref` set in `onMounted`, or derive it from something the server knows. - **Class or style differences you care about:** because these are not corrected, `data-allow-mismatch="class"` on a theme toggle leaves the server's class in place, silently, until the bound value next changes. - **As a blanket switch** on a layout root: an empty value on a high ancestor turns off text and children reporting for everything below it, including the next genuine bug. A good review rule is that every use carries a comment naming the inherent difference it accepts.
- Does `data-allow-mismatch` on a parent cover a text mismatch in a nested child?For text and children mismatches, yes: Vue walks up from the element to the nearest ancestor that has the attribute and checks its value. For class, style and attribute mismatches, no: only the element's own attribute is consulted. That asymmetry is why a blanket attribute high in the tree hides more than intended.
- Does the attribute affect production builds?Yes. Production logs a single generic `Hydration completed but contains mismatches.` error when a reportable mismatch occurs, and allowed mismatches do not trigger it. What does not change is recovery: text is still replaced, nodes are still re-mounted, and class, style and attribute values are still not rectified.
- Why is `data-allow-mismatch="class"` on a dark-mode wrapper a trap?Class mismatches are check-only, so the element keeps the server's class after hydration. Later updates compare the new vnode to the old client vnode, not to the DOM, so the wrong class stays until the bound value changes. Suppression removes the only signal that the theme is wrong.
saying these in an interview costs you the question
- data-allow-mismatch makes Vue keep the server-rendered content
- The value all allows every mismatch type
- It skips hydration for that element and its children
- A class permission on a parent also covers child class mismatches
- It is the standard fix for any hydration warning