Retour
Publié le Sep 3, 2024, mis à jour le Sep 6, 2024

Using new Date() in Nuxt

At some point in the development of your Nuxt JavaScript application, you will want to use the Date object using its constructor new Date() to get the current date or time.

const now = new Date()

By doing so, you will encounter a hydration mismatch error. This is because new Date() is executed on the server side during page generation and then on the client side during page hydration. Since the two dates are separated by a few milliseconds, Nuxt detects a difference in their respective values and returns a hydration mismatch warning in the console.

<script setup>
const now = new Date()
</script>

<template>
  <div>{{ now }}</div>
</template>

Solution

The simplest and most effective solution is to wrap new Date() in the Nuxt useState() function.

<script setup>
const now = useState(() => new Date())
console.log(now.value)
</script>

<template>
  <div>{{ now }}</div>
</template>

The value of now is now calculated on the server side and then sent to the client using Nuxt's payload variable1.

For more information: useState composable - Nuxt docs

Other approaches

Depending on the context, there are other ways to handle or work around this issue. However, it is important to keep in mind that the date returned by new Date() is different on the server side and the client side.

  • Using the Nuxt <ClientOnly> component2
<script setup>
const now = new Date()
</script>

<template>
  <ClientOnly>
    <h1>{{ now }}</h1>
  </ClientOnly>
</template>
  • Adding the .client.vue suffix to the page file3 or component file4 to ensure it is only executed on the client side.
  • Using the onMounted() hook provided by Vue.js5, which is not executed on the server side.
<script setup>
const now = ref()
onMounted(() => {
  now.value = new Date()
})
</script>
  • Alternatively, you can calculate the variable only on the server side by using the import.meta.server object6 from Nuxt. ⚠ now.value will be undefined on the client side!
<script setup>
const now = ref()
if (import.meta.server) {
  now.value = new Date()
}
</script>
  • Since Vue v3.5, it is possible to use the data-allow-mismatch attribute to suppress the hydration mismatch warning in the console7.

Footnotes

  1. 1. NuxtApp payload - Nuxt docs
  2. 2. <ClientOnly> - Nuxt docs
  3. 3. Client-only Pages - Nuxt docs
  4. 4. Client-only Components - Nuxt docs
  5. 5. onMounted - Vue.js docs
  6. 6. Import meta - Nuxt docs
  7. 7. data-allow-mismatch - Vue.js docs