All guidesMore providers: databases, auth, hosting, email and payments
On this page

Nuxt error

Nuxt

Hydration completed but contains mismatches.

By Ohad Krispin, founder of VibeRaven · LinkedIn

"Hydration completed but contains mismatches." is a Vue console error: the HTML the Nuxt server rendered is not what the browser rendered on its first pass. Vue logs it in production builds, once, and then patches the page to match the client. A cause that appears after deploy is a date or time formatted in the runtime's own time zone, because the server and each visitor's browser are in different zones, as the Vue docs note. In a test with the server started in UTC, it rendered 8:53:20 AM and a browser in Asia/Jerusalem rendered 11:53:20 AM. Use NuxtTime, or move the value into onMounted or ClientOnly. Reproduced with nuxt 4.5.2 on 2026-10-31.

What causes a hydration mismatch that only shows after deploy?

The Vue SSR guide lists three common causes: invalid HTML nesting that the browser corrects, randomly generated values in the render, and a server and client in different time zones. The Nuxt hydration guide adds browser-only APIs such as localStorage, checks on window, third-party libraries that change the DOM, and iOS Safari turning phone numbers and dates into links. Locally, the server and the browser share one machine and one time zone, so the date cause stays hidden until the server runs somewhere else.

page: <p>{{ new Date(1760000000000).toLocaleString('en-US') }}</p>
server (TZ=UTC):           10/9/2025, 8:53:20 AM
browser (Asia/Jerusalem):  10/9/2025, 11:53:20 AM
console:                   Hydration completed but contains mismatches.

How do I fix a date hydration mismatch in Nuxt?

The Nuxt docs say the NuxtTime component renders time consistently between server and client without hydration mismatches. In the same test, replacing the expression with NuxtTime printed no hydration message on a fresh load, and the browser showed its own time zone, 11:53:20 AM. The Nuxt guide also lists useState for random values, useCookie in place of localStorage, onMounted for libraries that need the DOM, and ClientOnly for browser-specific content.

<NuxtTime :datetime="1760000000000" date-style="short" time-style="medium" locale="en-US" />

Does Vue print this message in a production build?

Yes. In Vue's hydration.ts the message is not gated to development, and a code comment says it should show up in production. It prints once. The detailed warnings that name the element, such as "Hydration text mismatch in", run only in development or when a production feature flag is on, so run nuxt dev on the page to see which element differs.

Checklist

How to fix it, then check the fix

  1. 01
    Search the app for values that differ between the server and the browser:
    grep -rnE "new Date|toLocale|Intl\.|Math\.random|localStorage|window\.|document\." --include=*.vue --include=*.ts --exclude-dir=node_modules --exclude-dir=.nuxt --exclude-dir=.output .
  2. 02
    Run the page in development and read the first warning that names an element:
    npx nuxt dev
  3. 03Replace dates and times with NuxtTime, random values with useState, and localStorage reads with useCookie. Put code that needs the DOM in onMounted, or wrap the content in ClientOnly.
  4. 04Check the HTML for invalid nesting, such as a div inside a p.
  5. 05Redeploy, open the page in a browser with a time zone different from the server, and check that the console has no "Hydration completed" line.

Related

Sources

Official docs behind this checklist

FAQ

FAQ for builders before launch

Is it only a warning?

Vue says it tries to recover by discarding the wrong nodes and mounting new ones, which costs rendering performance, and that the app should in most cases keep working. The Nuxt guide treats mismatches as signs of problems that can break the application, so fix them instead of ignoring them.

Can I silence a mismatch I cannot avoid?

The Vue SSR guide says Vue 3.5 and later supports the data-allow-mismatch attribute for mismatches that are unavoidable. Use it on that element only, not to hide a date you can render with NuxtTime.