Home > Net >  Why NextJS give me this hydrating error after refreshing the page?
Why NextJS give me this hydrating error after refreshing the page?

Time:01-28

When I refresh my page I got these erorrs :

Text content does not match server-rendered HTML. Hydration failed because the initial UI does not match what was rendered on the server. There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.

This is my file code :

/* eslint-disable @next/next/no-img-element */
import Header from '@/components/Header'
import blockContent from '@/medium-sanity-copy/schemas/blockContent'
import { PostType, SlugType } from '@/types'
import { Formik, Field, Form, ErrorMessage } from 'formik'
import { FieldProps } from 'formik/dist/Field'
import { GetStaticProps } from 'next'
import Head from 'next/head'
import React from 'react'
import PortableText from 'react-portable-text'
import { client, urlFor } from './../../sanity'
import * as yup from 'yup'

interface PostProps {
  post: PostType
}
let schema = yup.object().shape({
  name: yup.string().required('Name field is required'),
  comment: yup.string().required('Comment field is required'),
  email: yup.string().email('Email field must be email type').required('Email field is required'),
})

const Post: React.FC<PostProps> = ({ post }) => {
  const initialValues = {
    name: '',
    email: '',
    comment: '',
  }
  return (
    <div className="mb-10">
      <Head>
        <title>{post.title}</title>
        <link rel="icon" href="https://cdn.iconscout.com/icon/free/png-256/medium-47-433328.png" />
      </Head>
      <Header />
      <div className="max-w-3xl mx-auto px-5 md:px-0">
        <div className="my-5">
          <h1 className="text-3xl font-bold mb-3">{post.title}</h1>
          <h2 className="text-xl text-gray-600">{post.description}</h2>
          <div className="flex items-center space-x-3 my-3">
            <img
              className="h-10 w-10 rounded-full drop-shadow-md"
              src={urlFor(post.author?.image).url()}
              alt="avatar"
            />
            <p className="font-extralight text-gray-600">
              Blog post by <span className="text-yellow-600">{post.author?.name}</span> - Published
              at {new Date(post._createdAt!).toLocaleString()}
            </p>
          </div>
        </div>
        <PortableText
          projectId={process.env.NEXT_PUBLIC_SANITY_PROJECT_ID}
          dataset={process.env.NEXT_PUBLIC_SANITY_DATASET}
          content={post.body!}
          serializers={{
            h1: (props: any) => <h1 className="text-2xl text-bold my-5" {...props} />,
            h2: (props: any) => <h2 className="text-xl text-bold my-5" {...props} />,
            li: ({ children }: any) => <li className="ml-4 list-disc">{children}</li>,
            link: ({ href, children }: any) => (
              <a href={href} className="text-blue-500 hover:underline">
                {children}
              </a>
            ),
          }}
        />
      </div>
      <hr className="color bg-yellow-600 h-1 max-w-xl mx-auto mt-10 mb-5" />
      <Formik
        initialValues={initialValues}
        onSubmit={(values) => {
          alert(`${values.comment}, ${values.email}, ${values.name}`)
        }}
        validationSchema={schema}>
        {() => (
          <Form className="max-w-2xl mx-auto p-5">
            <span className="text-yellow-600">Enjoyed this article?</span>
            <h1 className="text-3xl font-bold">Leave the comment below!</h1>
            <hr className="my-2" />
            <div className="flex flex-col my-3">
              <label htmlFor="name">Name</label>
              <Field name="name">
                {({ field }: FieldProps) => (
                  <input
                    type="text"
                    {...field}
                    className="outline-none border py-2 px-3 rounded shadow"
                  />
                )}
              </Field>
            </div>
            <div className="flex flex-col my-3">
              <label htmlFor="email">Email</label>
              <Field name="email">
                {({ field }: FieldProps) => (
                  <input
                    type="text"
                    {...field}
                    className="outline-none border py-2 px-3 rounded shadow"
                  />
                )}
              </Field>
            </div>
            <div className="flex flex-col my-3">
              <label htmlFor="comment">Comment</label>
              <Field name="comment">
                {({ field }: FieldProps) => (
                  <textarea
                    {...field}
                    rows={8}
                    className="outline-none border resize-none py-2 px-3 rounded shadow"
                  />
                )}
              </Field>
            </div>
            <div className="flex flex-col space-y-1 text-red-500 items-center">
              <ErrorMessage name="name">{(err) => <span>{err}</span>}</ErrorMessage>
              <ErrorMessage name="email">{(err) => <span>{err}</span>}</ErrorMessage>
              <ErrorMessage name="comment">{(err) => <span>{err}</span>}</ErrorMessage>
            </div>
          </Form>
        )}
      </Formik>
    </div>
  )
}

export default Post

export const getStaticPaths = async () => {
  const query = `
    *[_type == "post"]{
        _id,
        slug
      }
    `

  const posts = await client.fetch(query)

  const paths = posts.map((post: { _id: string; slug: SlugType }) => ({
    params: {
      slug: post.slug.current,
    },
  }))
  return { paths, fallback: false }
}

export const getStaticProps: GetStaticProps = async ({ params }) => {
  const query = `
    *[_type == "post" && slug.current == $slug][0]{
        _id,
        _createdAt,
        description,
        slug,
        mainImage,
        title,
        author -> {
          name,
          image
        },
        body
      }
    `
  const post = await client.fetch(query, { slug: params?.slug })

  return {
    props: {
      post,
    },
    revalidate: 60,
  }
}

I didn't find out a solution that I can understand and agree with

CodePudding user response:

This is usually caused when you have a <div> or <h1> element inside a <p> elemnt.

You can find what is causing this issue if you check the console

  • Related