Dynamic metadata is not working
Unanswered
Rajan posted this in #help-forum
RajanOP
Meta tag is added and visible in the page source but preview of the page link is not working
import type { Metadata, ResolvingMetadata } from "next";
import ChatScreen from "@/page/chatpage";
type Props = {
params: { slug: Array<string> };
searchParams: { [key: string]: string | string[] | undefined };
};
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
// read route params
const id = params.slug[0];
return {
title: "product title",
description: "This is my app",
openGraph: {
type: "website",
title: "Product Title",
description: "This is my app",
},
twitter: {
title: "Product Title",
description: "This is my app",
},
};
}
export default function Home({ params }: { params: { slug: string } }) {
return <ChatScreen slug={params.slug} />;
}view-source:https://d42a2f857f2e54b22164c2918569feb8.serveo.net/conversation/7e43b549-0554-44c9-b838-75c521999a1344 Replies
RajanOP
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/a34f9d1faa5f3315-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/app/layout.css?v=1727174460020" data-precedence="next_static/css/app/layout.css"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack.js?v=1727174460020"/><script src="/_next/static/chunks/main-app.js?v=1727174460020" async=""></script><script src="/_next/static/chunks/app-pages-internals.js" async=""></script><script src="/_next/static/chunks/app/conversation/%5B%5B...slug%5D%5D/page.js" async=""></script><script src="/_next/static/chunks/app/layout.js" async=""></script><script src="https://chief-hawk-0.clerk.accounts.dev/npm/@clerk/clerk-js@5/dist/clerk.browser.js" data-clerk-js-script="true" async="" crossorigin="anonymous" data-clerk-publishable-key="pk_test_Y2hpZWYtaGF3ay0wLmNsZXJrLmFjY291bnRzLmRldiQ"></script><title>AI Chatbot</title><title>product title</title><meta name="description" content="This is my app"/><meta property="og:title" content="Product Title"/><meta property="og:description" content="This is my app"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary"/><meta name="twitter:title" content="Product Title"/><meta name="twitter:description" content="This is my app"/><link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="32x32"/><link rel="icon" href="/icon.png?544588905e8aa162" type="image/png" sizes="545x545"/><meta name="next-size-adjust"/>Without an image what else do social media sites have to embed?
@joulev I think you need to add an open graph image url as well
RajanOP
I added this as well
import type { Metadata, ResolvingMetadata } from "next";
type Props = {
params: { id: string };
searchParams: { [key: string]: string | string[] | undefined };
};
export async function generateMetadata(
{ params, searchParams }: Props,
parent: ResolvingMetadata
): Promise<Metadata> {
console.log({ params, searchParams });
// read route params
// const id = params.id
// // fetch data
// const product = await fetch(`https://.../${id}`).then((res) => res.json())
// // optionally access and extend (rather than replace) parent metadata
// const previousImages = (await parent).openGraph?.images || []
return {
title: "My App",
description: "This is my app",
openGraph: {
title: "Next.js",
description: "The React Framework for the Web",
url: "https://nextjs.org",
siteName: "Next.js",
},
twitter: {
card: "summary_large_image",
title: "Next.js",
description: "The React Framework for the Web",
siteId: "1467726470533754880",
creator: "@nextjs",
creatorId: "1467726470533754880",
},
};
}
export default function Layout({ children }: { children: React.ReactNode }) {
return <>{children}</>;
}still it's not working
only for the this dynamic page when i try to do it for static page it's working totally fine
Or add an opengraph-image.png https://nextjs.org/docs/app/api-reference/file-conventions/metadata/opengraph-image#opengraph-image
https://da67b9652e70fe60d11d391d8df79965.serveo.net/conversation/ca319be6-0271-4dda-af04-3fb04872824e
for this page it's added the meta data in source page but i want the preview as well
for this page it's added the meta data in source page but i want the preview as well
but it's not showing here
Ok lemme have a look when I reach my laptop
Gonna take a while though
RajanOP
sure
it's works fine in static page but not in the dynamic one
@Rajan https://da67b9652e70fe60d11d391d8df79965.serveo.net/home
RajanOP
I want similar like this in this (https://da67b9652e70fe60d11d391d8df79965.serveo.net/conversation/ca319be6-0271-4dda-af04-3fb04872824e) page
@Rajan sure
While you wait, put your app to some open graph checker like https://www.opengraph.xyz and see what it suggests
RajanOP
already did throwing error

actually i'm using a ip tunnel for test this meta data
is it okay or i need to push it my server and check it over there?
@Rajan Click to see attachment
Seems like it’s the checker’s skill issue, try another one. Google should give you plenty of options
RajanOP
tried twitter there too
still same issue
what might be the problem
I have to fetch data from an api and displaying it instead directly or put static data
simply
@Rajan https://da67b9652e70fe60d11d391d8df79965.serveo.net/home
i got 502, your site is not online
@joulev i got 502, your site is not online
RajanOP
Actually I used serveo for localhost ip tunneling
Please use the app.staging.charsnap.ai
need to not have any auth wall for crawlers to see the meta tags
RajanOP
yes you're right
actually it's a protected route
that's why it's crawling the metadata
after configured in the middleware it's working fine
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
const clerkSecretKey = process.env.NEXT_PUBLIC_CLERK_SECRET_KEY;
const isPublicRoute = createRouteMatcher([
"/",
"/home",
"/sign-in",
"/sign-up",
"/sign-up/sso-callback(.*)",
"/terms",
"/privacy",
"/sign-in/forgot-password",
]);
export default clerkMiddleware(
(auth, req) => {
const pathname = req.nextUrl.pathname;
if (pathname.startsWith("/api/metadata")) {
return NextResponse.next();
}
if (!isPublicRoute(req)) {
auth().protect();
}
if (
auth().userId &&
["/", "/sign-up", "/sign-in", "/sign-in/forgot-password"].includes(pathname)
) {
return NextResponse.redirect(new URL("/home", req.url));
}
},
{
secretKey: clerkSecretKey,
}
);
export const config = {
matcher: [
"/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
"/(api|trpc)(.*)",
],
};@joulev Click to see attachment
RajanOP
thanks for your help man