Vite, Vue3, Koa SSR error `Hydration completed but contains mismatches`

333 views Asked by At

I'm currently working on converting an existing Vue 3 front-end project into an SSR (Server-Side Rendering) project using Vite, Vue 3, Pinia, vue-i18n and Koa. However, I've run into an issue. My repository is available.

kun-galgame-vue

The key code is: index.html, server-dev.ts, server-prod.ts, entry-client.ts, entry-server.ts, vite.config.ts

A similar issue is https://github.com/vitejs/vite/issues/7900

I've searched for some related articles and discussions, but due to the console error showing only a one-liner error message without specifying which component is causing the issue, I can't pinpoint the exact reason for the error.

[Vue][SSR] Suppress hydration mismatch warning

When run pnpm dev ("dev": "ts-node-esm server-dev.ts"), an error occurred

The console error is

entry-client.ts:19 [Vue warn]: Hydration node mismatch:

  • Client vnode: Symbol(v-fgt)
  • Server rendered DOM:
    at warn2 @ runtime-core.esm-bundler.js:41 handleMismatch @ runtime-core.esm-bundler.js:4869 onMismatch @ runtime-core.esm-bundler.js:4538 hydrateNode @ runtime-core.esm-bundler.js:4615 hydrateSubTree @ runtime-core.esm-bundler.js:5723 componentUpdateFn @ runtime-core.esm-bundler.js:5743 run @ reactivity.esm-bundler.js:178 instance.update @ runtime-core.esm-bundler.js:5862 setupRenderEffect @ runtime-core.esm-bundler.js:5870 mountComponent @ runtime-core.esm-bundler.js:5660 hydrateNode @ runtime-core.esm-bundler.js:4651 hydrate2 @ runtime-core.esm-bundler.js:4529 mount @ runtime-core.esm-bundler.js:3830 app.mount @ runtime-dom.esm-bundler.js:1468 (anonymous) @ entry-client.ts:19 Promise.then (async) (anonymous) @ entry-client.ts:18

entry-client.ts:19 Hydration completed but contains mismatches.

It seems that SSR didn't take effect for the rendered HTML console error

The project I referenced is koa2-ssr-vite-vue3-ts-pinia. From this project, it can be seen that <!--ssr-outlet--> is correctly replaced with the rendered HTML. However, in my project, <!--ssr-outlet--> remains unchanged and is not replaced.

Here are some other related SSR projects where you can see the rendered pages in the browser preview, but my page is blank:

https://github.com/dmoosocool/vite-koa-ssr

I use Vue 3's Teleport in the code, which seems to cause hydration mismatches

https://vuejs.org/guide/scaling-up/ssr.html#teleports

<template>
  <Teleport to="body" :disabled="showAlert">
    <Transition name="alert">
      <div v-if="showAlert" class="mask">
        ...
      </div>
    </Transition>
  </Teleport>
</template>

I also use a few native DOM operations and the browser's fetch API to fetch backend data:

    // Set the theme, there are only two modes
    // , light and dark, with light represented as ''
    setKUNGalgameTheme(theme: '' | 'dark') {
      this.showKUNGalgameMode = theme
      document.documentElement.className = theme
    },
// Fetch request function
const kunFetchRequest = async <T>(
  url: string,
  options: FetchOptions
): Promise<T> => {
  const baseUrl = import.meta.env.VITE_API_BASE_URL
  const fullUrl = `${baseUrl}${url}`

  // Add the token to the request headers
  const headers = {
    ...options.headers,
    Authorization: `Bearer ${useKUNGalgameUserStore().getToken()}`,
  }

  const response = await fetch(fullUrl, { ...options, headers })

  // If not 20X, then throw an error
  if (!successResponseArray.includes(response.status)) {
    // Handle errors, such as token expiration
    await onRequestError(response)
    throw new Error('KUNGalgame Fetch Error occurred, but no problem')
  }

  const data: T = await response.json()
  return data
}
0

There are 0 answers