3

I am getting dynamic title and log from API and passing it to nextJS Head for og:title and og:image. but it is not working. Any idea how can I make it work.

Here is my code.

function PageHead(props: any) {
  let location = "/";
  if (process.browser) {
    location = window.location.href;
  }
  console.log(props);
    
  return (
    <Head>
      <meta property="og:title" content={props.title} />
      <meta property="og:url" content={location} />
      <meta property="og:image" content={props.logo} />
    </Head>
  );
}

const Home: NextPage = () => {
  const [title, setTitle] = useState('');
  const [logo, setLogo] = useState('');
  useEffect(() => {
    (async () => {
      const reviewData = await (await fetch("https://api.")).json();
      setTitle(reviewData.name);
      setLogo(reviewData.logo);
    })();
  }, []);

  return (
    <React.Fragment>
      <Box
        sx={{
          display: 'flex',
          flexDirection: 'column',
          minHeight: '100vh',
        }}
      >
        <PageHead logo={logo} title={title}/>
       
      </Box>
    </React.Fragment>
  )
}

export default Home

After I export static site or run as a dev. when I refresh the page, in console.log I get the following 3 logs one after another. This tells me that it does get the logo and title from api one by one and refresh console but for some reason does not populate it within HEAD for title and image tag.

Any idea how can I fix it.

enter image description here

Developer
  • 25,073
  • 20
  • 81
  • 128

1 Answers1

1

You need to init your page header at build time for SEO purpose

If you fetch data after your app has been rendered on the client-side. It's not meaningful for SEO anymore, because Search Engine Bot can't read your header at that time.

So you need to render your Header component on the server at build time.

Next.js provided you some method to support you fetch data at build time for all cases (server-side rendering, static site generate, incremental site regenerate...)

Here is their official documentation: https://nextjs.org/docs/basic-features/data-fetching

Here is an example for static generate my Blog detail page:

export const getStaticProps = async ({ params }) => {
  const response = await fetchAPI(params.slug); // Fetch your data

  // Response 404 page if data is failed to fetch
  if (!response.success) {
     return { notFound: true };
  }

  const { title, description, images } = response;

  return {
     props: {
        pageHeader: {
           title: name,
           metas: [
              {
                 name: 'description',
                 content: description,
              },
              { property: 'og:title', content: name },
              {
                 property: 'og:image',
                 content: images[0] || null,
              },
              {
                 property: 'og:description',
                 content: description,
              },
           ],
        },
        productData: response,
     },
     revalidate: 5 * 60, // re-generate each 5 minutes
  };
};

And all data fetched above will be passed to your Page Component. You can use these data props to render your Page Header at build time. This Header will be included in your first HTML document. Then Search Engine Bot can read and handle that.

import Head from 'next/head';

const BlogDetailPage = (pageProps) => (
   <>
      <Head>
        <title>{pageProps.pageHeader.title}</title>
        {pageProps.pageHeader.metas.map((attributes, index) => (
          <meta {...attributes} key={index} />
        ))}
      </Head>
      <YourPageComponent />
   </>
);
Justin Lu
  • 26
  • 3
  • Thanks, Justin, I can understand that, But I need it to load dynamically from API from a static page. which means if the value change in API, I don't want to regenerate the static site again, instead it updates the title automatically. Like it is doing for the rest of the page to update the logo and title (but for Head) it does not work for some reason... – Developer Sep 07 '21 at 21:30
  • Hi @Developer, I got your point and I saw that the `` component is just responsible for rendering and not binding to update parallel with your props. So to update it base on your API response. You could use DOM manipulation to do that like the example below after your API responded successfully: https://stackoverflow.com/a/62332670/16633962 – Justin Lu Sep 09 '21 at 14:02