Next.js Discord

Discord Forum

Meta Data and OpenGraph

Answered
Tibetan Mastiff posted this in #help-forum
Open in Discord
Tibetan MastiffOP
Hey, I've searched all the discussions about OpenGraph but couldn't find an answer to my specific issue, so I decided to create a new post.

I'm currently wrestling with OpenGraph meta tags, and I've got a few questions that have been bugging me. I've been using the recommended approach of defining a meta data object for my pages. This object allows you to specify various meta tags, including OpenGraph tags (see attached screenshot). However, I've run into a snag:

When I define OpenGraph tags in the meta data object, they don't seem to generate the corresponding HTML tags like <meta property="og:image" content="url"/>. What gives?

To work around this, I've manually added the <meta property="og:image" content="url"/> tag in my component's return statement.

This leads me to wonder:

Is my workaround a valid approach?
Do I even need to use NextJs's <Head></Head> component? When I wrap my meta tag with <Head>, it doesn't seem to work. Is <Head> still relevant for this?

Finally, what's the correct way to implement OpenGraph tags? I've read through some of the docs but haven't found a clear answer. If anyone could point me to some resources that directly address my questions, I'd be grateful.

Off-topic:
I had a similar issue with the meta object when trying to add JSON-LD data. I managed to get it working with another workaround, but it's frustrating that the meta object doesn't seem to support JSON-LD out of the box.

I hope my question and the attached screenshot make my issue clear. Looking forward to your insights!
Answered by Mossyrose gall wasp
import cn from "classnames";
import type { Metadata } from "next";

import Footer from "@/components/Footer";
import Header from "@/components/Header";


import { gilroy, oktaNeue } from "@/utils/helper/font";

import { i18n } from "../../../i18n-config";

import "../../styles/index.scss";

const data = {
  type: "home",
  context: "http://schema.org",
  title: "Test",
  images: ["/icon-192x192.png"],
  description: "Test Description",
  themeColor: "#fff",
  openGraph: {
    title: "Test",
    description: "Test Description",
    url: "https://example.com/",
    siteName: "Test",
    images: [
      {
        url: "/static/og/og.jpg",
        width: 800,
        height: 600,
      },
    ],
    type: "website",
  },
  twitter: {
    card: "summary_large_image",
    title: "Test",
    description: "test Description",
    creator: "@test",
    images: ["/static/og/og.jpg"],
  },
  icons: [
    {
      rel: "icon",
      type: "image/png",
      url: "/static/og/favicon.ico",
    },
  ],
  manifest: "/manifest.json",
};

export const metadata: Metadata = {
  ...data,
};

export async function generateStaticParams() {
  return i18n.locales.map((locale) => ({ lang: locale }));
}

export default async function RootLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { lang: string };
}) {
  return (
    <html
      lang={params.lang}
      dir={params.lang}
      className={cn(gilroy.variable, oktaNeue.variable)}
    >
      <body className="">
            <Header />
            {children}
            <Footer />
        </HeaderProvider>
      </body>
    </html>
  );
}

This is how i achieved my last project using appDir and metadata.
View full answer

3 Replies

Mossyrose gall wasp
import cn from "classnames";
import type { Metadata } from "next";

import Footer from "@/components/Footer";
import Header from "@/components/Header";


import { gilroy, oktaNeue } from "@/utils/helper/font";

import { i18n } from "../../../i18n-config";

import "../../styles/index.scss";

const data = {
  type: "home",
  context: "http://schema.org",
  title: "Test",
  images: ["/icon-192x192.png"],
  description: "Test Description",
  themeColor: "#fff",
  openGraph: {
    title: "Test",
    description: "Test Description",
    url: "https://example.com/",
    siteName: "Test",
    images: [
      {
        url: "/static/og/og.jpg",
        width: 800,
        height: 600,
      },
    ],
    type: "website",
  },
  twitter: {
    card: "summary_large_image",
    title: "Test",
    description: "test Description",
    creator: "@test",
    images: ["/static/og/og.jpg"],
  },
  icons: [
    {
      rel: "icon",
      type: "image/png",
      url: "/static/og/favicon.ico",
    },
  ],
  manifest: "/manifest.json",
};

export const metadata: Metadata = {
  ...data,
};

export async function generateStaticParams() {
  return i18n.locales.map((locale) => ({ lang: locale }));
}

export default async function RootLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { lang: string };
}) {
  return (
    <html
      lang={params.lang}
      dir={params.lang}
      className={cn(gilroy.variable, oktaNeue.variable)}
    >
      <body className="">
            <Header />
            {children}
            <Footer />
        </HeaderProvider>
      </body>
    </html>
  );
}

This is how i achieved my last project using appDir and metadata.
Answer
@Mossyrose gall wasp jsx import cn from "classnames"; import type { Metadata } from "next"; import Footer from "@/components/Footer"; import Header from "@/components/Header"; import { gilroy, oktaNeue } from "@/utils/helper/font"; import { i18n } from "../../../i18n-config"; import "../../styles/index.scss"; const data = { type: "home", context: "http://schema.org", title: "Test", images: ["/icon-192x192.png"], description: "Test Description", themeColor: "#fff", openGraph: { title: "Test", description: "Test Description", url: "https://example.com/", siteName: "Test", images: [ { url: "/static/og/og.jpg", width: 800, height: 600, }, ], type: "website", }, twitter: { card: "summary_large_image", title: "Test", description: "test Description", creator: "@test", images: ["/static/og/og.jpg"], }, icons: [ { rel: "icon", type: "image/png", url: "/static/og/favicon.ico", }, ], manifest: "/manifest.json", }; export const metadata: Metadata = { ...data, }; export async function generateStaticParams() { return i18n.locales.map((locale) => ({ lang: locale })); } export default async function RootLayout({ children, params, }: { children: React.ReactNode; params: { lang: string }; }) { return ( <html lang={params.lang} dir={params.lang} className={cn(gilroy.variable, oktaNeue.variable)} > <body className=""> <Header /> {children} <Footer /> </HeaderProvider> </body> </html> ); } This is how i achieved my last project using appDir and metadata.
Tibetan MastiffOP
Thank you for sharing your solution!

It also works for me. It's very interesting seeing that working, since that's exactly I would have expected it to work. Now I need to find out where my mistake was.

Since your reply was the answer of my main question I will mark your reply as the solution. Thank you again!
Mossyrose gall wasp
happy to help