Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid Duplicate Meta Description and Keywords in Next.js

I'm developing my website with Next.js To upgrade my website's SEO performance, I'm trying to avoid duplicated meta tags.

My Question

In Next official docs, they say that I can avoid overlapped meta tag by insert key property in meta tag. But this does not work.

<meta name="description" content="~~" key="titleDescription"/>
<meta name="keywords" content="~~" key="titleKeywords"/>

These are default rootDocument meta tags and,

<meta name="description" content={item.product_description} key="titleDescription"></meta>
<meta name="keywords" content={item.brand_name} key="titleKeywords"></meta>

These are dynamically generated meta tags in item pages.

In deployed browser, there are still two description and keywords meta tags in website. I want to avoid duplicated meta tag. Thank you for your help!

like image 712
Han Avatar asked Jan 24 '23 07:01

Han


1 Answers

There are a few things to watch for when using Next.js Head components.

  • The _document Head component is next/document
  • Tags in _document will not be replaced (can be duplicated) even with a key identifier
  • The _app Head component is next/head
  • Tags in _app can be in child components
  • Tags in _app can be overridden with the key identifier
  • Tags in pages cannot be in child components
  • Tags in pages can override tags with the same key identifier.

Examples


_document.{js|jsx|ts|tsx}

Scripts, styles, and other tags you need access to immediately - Next will likely not be fully mounted at this point. You cannot replace tags in the document/head component with the key attribute.

import Document, {Head, Html, Main, NextScript } from 'next/document';
class MyDocument extends Document {
  render = () => (
    <Html lang="en-US" dir="ltr">
      <Head>
        <script src="/some-script.js" defer={false} />
        <style>.inline-styles{}</style>
        {/* META & TITLE TAGS PLACED HERE CANNOT BE OVERRODE */}
      </Head>
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

OR self-closing Head tag

class MyDocument extends Document {
  render = () => (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Note: import is from next/document


_app.{js|jsx|ts|tsx}

import Head from 'next/head';

const App = ({ Component, pageProps }) => (
  <>
    <Head>
      <title key="title">App Tittle</title>
    </Head>
    <Component {...pageProps} />
  </>
);

OR load from a custom component

import Head from 'next/head';

const MyHeadTags = () => (
 <Head>
  <title key="title">App Tittle</title>
  <meta key="description" name="description">Description</meta>
 </Head>
);

const App = ({ Component, pageProps }) => (
  <>
    <MyHeadTags />
    <Component {...pageProps} />
  </>
);

Note: import is from next/head


some_page.{js|jsx|ts|tsx}

const SomePage = () => (
  <>
    <Head>
      <title key="title">Some Page Tittle</title>
      <meta key="description" name="description">Some Page Description</meta>
    </Head>
    <div>My Page</div>
  </>
);

NOT ALLOWED

The head component must be on the page and cannot be a child component. If it's a child component, it sometimes will not override other tags with the same key property.

some_page.{js|jsx|ts|tsx}

const MyHeadTags = () => (
 <Head>
  <title key="title">Some Page</title>
  <meta key="description" name="description">Some Page Description</meta>
 </Head>
);

const ChildComponent = () => (
 <>
  <MyHeadTags />
  Info.
 </>
);

const SomePage= () => (
  <>
    <ChildComponent />
    <div>Will not work</div>
  </>
);

Update: The last example seems to work in some cases with Next 11+, but I have run into a few instances where it duplicates tags. I avoid the last method.

like image 58
Sean W Avatar answered Jan 27 '23 12:01

Sean W