generateMetaData not working
Answered
Giant Angora posted this in #help-forum
Giant AngoraOP
I'm putting generateMetaData for my app and it wont show metadata in embed previewers
143 Replies
Giant AngoraOP
export async function getProfe(handle) {
const supabase = await createClient();
const profeRes = await supabase
.from("profes")
.select("*")
.eq("handle", handle)
.single();
return profeRes.data;
}
export async function getMetadata(data) {
const title = data ? `${data.display_name} | Profe` : "Profile not found | Profe";
const handle = data ? `${data.handle}` : "profe";
const description = `Meet ${data.display_name || "Me"} On Profe`;
const url = data ? `https://profe-alpha.vercel.app/${data.handle}` : "https://profe-alpha.vercel.app";
const image = data ? `${process.env.NEXT_PUBLIC_HOST}/p/${data.handle}/opengraph-image` : "https://cdn.profe.app/default-avatar.png";
return (
{title,handle,description,url,image}
)
}
export async function generateMetadata({ params }) {
const {profeHandle} = params
const profe = await getProfe(profeHandle)
const metadata = await getMetadata(profe)
if (!profe) {
return {
title: "Profe not found | Profe",
description: "This Profe does not exist.",
}
}
return {
title: metadata.title,
description: metadata.description,
openGraph: {
title: metadata.title,
description: metadata.description,
url: metadata.url,
siteName: "Profe",
type: "profile",
images: [
{
url: metadata.image,
width: 1200,
height: 630
},
],
},
twitter: {
card: "summary_large_image",
title: metadata.title,
description: metadata.description,
images: [metadata.image]
}
}
}When in send route url in Discord , it wont show its embed
Title too , it wont change website title in browsers
Also , i used <head> , it worked , it show tab title , or work in embed previewers , but overall it not work on DIscord
Also , i used <head> , it worked , it show tab title , or work in embed previewers , but overall it not work on DIscord
Giant AngoraOP
Here
My home route will send an embed
But when i come for /app/p/[profeHandle]/layout.jsx ( above file ) , it wont send embed with below link
@Giant Angora When in send route url in Discord , it wont show its embed
any error logs on your deployment site?
it probably wont work on discord because you didnt meet the embed requirement of discord
im suspecting it has something to do with image being too large
if theres no error and discord is the only problem, i suggest troubleshooting metadata locally in dev (through a tunnel) and see what causes it to fail in discord
@alfonsüs ardani any error logs on your deployment site?
Giant AngoraOP
Nothing
@alfonsüs ardani it probably wont work on discord because you didnt meet the embed requirement of discord
Giant AngoraOP
Actually , i tried something recently
With this code :
With this code :
export async function generateMetadata ({ params }) {
const {profeHandle} = await params
if (!profeHandle) {
return {
title: "Profe not found | Profe",
description: "This Profe does not exist.",
}
}
return {
title: `${profeHandle} is title`,
description: `${profeHandle} is description`,
openGraph: {
title: `${profeHandle} is title`,
description: `${profeHandle} is description`,
url: `${profeHandle}.com`,
siteName: "Profe",
type: "profile",
},
twitter: {
card: "summary_large_image",
title: `${profeHandle} is title`,
description: `${profeHandle} is description`,
}
}
}
export default async function ProfeLayout({ params }) {
const {profeHandle} = params
return (
<html>
<body>
<p>{profeHandle}</p>
</body>
</html>
)
}@Giant Angora Actually , i tried something recently
With this code :
js
export async function generateMetadata ({ params }) {
const {profeHandle} = await params
if (!profeHandle) {
return {
title: "Profe not found | Profe",
description: "This Profe does not exist.",
}
}
return {
title: `${profeHandle} is title`,
description: `${profeHandle} is description`,
openGraph: {
title: `${profeHandle} is title`,
description: `${profeHandle} is description`,
url: `${profeHandle}.com`,
siteName: "Profe",
type: "profile",
},
twitter: {
card: "summary_large_image",
title: `${profeHandle} is title`,
description: `${profeHandle} is description`,
}
}
}
export default async function ProfeLayout({ params }) {
const {profeHandle} = params
return (
<html>
<body>
<p>{profeHandle}</p>
</body>
</html>
)
}
Giant AngoraOP
Its just a simple opengraph sample , its showing og successfully on app , og viewer and discord
Also with its opengraph-image.js :
Also with its opengraph-image.js :
import { ImageResponse } from 'next/og'
export const alt = 'Opengraph Image'
export const size = {
width: 1200,
height: 630,
}
export const contentType = 'image/png'
export default async function Image({ params }) {
const {profeHandle} = params
return new ImageResponse(
(
<div
style={{
width: "1200px",
height: "630px",
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
overflowY: "scroll",
position: "relative",
top: 0,
left: 0,
zIndex: 3
}}
>
<p
style={{
fontSize: "24px",
fontWeight: "400",
fontFamily: "Geist",
color: "red",
}}
>/{profeHandle}</p>
</div>
),
)
}Giant AngoraOP
But this is my main code where i want to deploy , and it wont provide og
https://gist.github.com/ThisIsTheMatin/52620351926fd045387d87fabf9b542e
https://gist.github.com/ThisIsTheMatin/52620351926fd045387d87fabf9b542e
Giant AngoraOP
Ok , now try with https://profe-alpha.vercel.app/p/thematin
@alfonsüs ardani
And code behind that...
export async function getProfe(handle) {
const supabase = await createClient();
const profeRes = await supabase
.from("profes")
.select("*")
.eq("handle", handle)
.single();
return profeRes.data;
}
export async function getMetadata(data) {
return {
title: data ? `${data.display_name} | Profe` : "Profile not found | Profe",
handle: data ? `${data.handle}` : "Profile Not Found",
description: data ? `Meet ${data.display_name || "Me"} On Profe` : "Profile Not Found",
url: data ? `https://profe-alpha.vercel.app/${data.handle}` : "https://profe-alpha.vercel.app",
image: data ? `${process.env.NEXT_PUBLIC_HOST}/p/${data.handle}/opengraph-image` : "https://cdn.profe.app/default-avatar.png",
}
}
export async function generateMetadata ({ params }) {
const {profeHandle} = await params
const profe = await getProfe(profeHandle)
const metadata = await getMetadata(profe)
if (!profe) {
return {
title: "Profe not found | Profe",
description: "This Profe does not exist.",
}
}
return {
title: metadata.title,
description: metadata.description,
openGraph: {
title: metadata.title,
description: metadata.description,
url: metadata.url,
siteName: "Profe",
type: "profile",
images: [
{
url: metadata.image,
width: 1200,
height: 630
},
],
},
twitter: {
card: "summary_large_image",
title: metadata.title,
description: metadata.description,
images: [metadata.image]
}
}
}
export default async function ProfeLayout({ params }) {
Other things...your image link is not working. make sure you have correct image link.
I had something more interesting...
code is correct but image link is not working 

Giant AngoraOP
When page loads
thats another problem -> make separate post
Giant AngoraOP
Its completely shows everything
But
In a sec , it come with nothing ...
what does this have anything to do with generateMetaData?
@alfonsüs ardani what does this have anything to do with generateMetaData?
Giant AngoraOP
It's title
@Giant Angora In a sec , it come with nothing ...
thats because your generateMetaData is async
its normal if it has no cache
its normal if you dont use any caching
Giant AngoraOP
Go in that page and you will see title will load for a moment and then , it will show url again
@alfonsüs ardani its normal if you dont use any caching
Giant AngoraOP
Wym
wym wym?
you have loading UI, that uses suspense. that means any other async functions like your async generateMetaData can be deferred later
that mean blank page/loading ui is sent ASAP while other are still loading
to solve it, use caching
so that generateMetadata runs instantly
this is off topic
@alfonsüs ardani wym wym?
Giant AngoraOP
I mean my layout.jsx do data fetching and rendering client component based of some user authorization conditions
make another thread if you have another issue
@alfonsüs ardani
Hey , check this out , og image is working but it still not working on Discord
It's not related to og image you marked it as solution dude 😅
Giant AngoraOP
I don't know , but you worked with Supabase?
how is that relevant
Giant AngoraOP
Cause
export async function generateMetadata({ params }) {
const {profeHandle} = params
return {
title: `${profeHandle} as title`
}
}
export default async function ProfeLayout({ params }) {
return (
<p>{await params.profeHandle}</p>
)
}This naturally working
Cause its just a title return based of params
No fetch , nothing
But when i use main code for og , it start fetching data and mixing some objects in together to just get a final og data
wtf 😭
Giant AngoraOP
And , will this make og generation too long?
try converting it to webp first
@alfonsüs ardani dude 100MB picture
Giant AngoraOP
Dude whenever i don't use og image , it still not working
Its a 6 month problem for my app
With or without og image
what problem
Giant AngoraOP
export const alt = 'Opengraph Image'
export const size = {
width: 1200,
height: 630,
}
export const contentType = 'image/png'
export default async function Image({ params }) {
const {profeHandle} = params
const supabase = await createClient()
const profe = await supabase.from("profes").select("*").eq("handle",profeHandle).single()
const data = profe.data.data
console.log(data)
const profePremium = await getProfePremium(profe && profe.data ? profe.data.id : null)
const isPremiumValid = profePremium && profePremium.data
? new Date() <= new Date(profePremium.data.end_time)
: false;
const profeTheme = await getTheme(profe && profe.data ? profe.data.user : null)
const theme = profeTheme.data.find(theme => theme.id == profe.data.theme).theme || null
const geistBlack = fetch(
"https://khlahvgbqpyjfmwrjayp.supabase.co/storage/v1/object/public/cortik/fonts/Geist-Black.ttf"
).then(res => res.arrayBuffer())
const geistRegular = fetch(
"https://khlahvgbqpyjfmwrjayp.supabase.co/storage/v1/object/public/cortik/fonts/Geist-Regular.ttf"
).then(res => res.arrayBuffer())
return new ImageResponse(
(1200px in 630px are making it >100mb ?
no, the file itself is making it 100mb
@alfonsüs ardani no, the file itself is making it 100mb
Giant AngoraOP
How?
@alfonsüs ardani dude 100MB picture
Giant AngoraOP
100060 bytes dude
ChatGPT offered using params
But its actually shit
In og image , i need user ui data , display name , username
Its impossible to continue without fetching data from Supabase
🧭 Why you briefly see the correct title then it reverts
This happens because:
On client navigation, the generateMetadata for the target route might reuse some cached data or prefetch, briefly setting correct title.
But on full page refresh (hard reload), generateMetadata runs first, before any React rendering or Supabase session → returns empty metadata.
Next.js sees no valid title and falls back to the current URL as the document title.
This happens because:
On client navigation, the generateMetadata for the target route might reuse some cached data or prefetch, briefly setting correct title.
But on full page refresh (hard reload), generateMetadata runs first, before any React rendering or Supabase session → returns empty metadata.
Next.js sees no valid title and falls back to the current URL as the document title.
i have no idea why the preview didnt show up
this is a very rare edge case
Giant AngoraOP
Its goin more strange when og previewer show it fully loaded up
And app itself cant load image or title
Or Discord
its not strange because i coded that and its only mimicking behavior not one-to-one accuracy
it seem to not work on X either
Giant AngoraOP
Yeah i tried Telegram or Whatsapp too
Answer
Giant AngoraOP
Ohhh
Return 500 and show page?
no, return 500, blank page, but shows metadata
thats why check-site-meta can pick it up
maybe investigate further whats causing this
like comment out unecessary code
to see who is awaiting who
i mean the structure of your layout/loading/page and suspense and stuff
@alfonsüs ardani no, return 500, blank page, but shows metadata
Giant AngoraOP
Awwww
You mean check site meta just get metadata from page , whatever happens
yeah
Giant AngoraOP
But app and some platforms care about page result
If it just go 200
they just have stricter checks yeah
can't blame me, i can't possibly know all those checks 

Giant AngoraOP
Dude dont say that
You are helping me
To develop my platform
Whatever at og or other things
oh okay
glad i could help
Giant AngoraOP
Thanks 🔥
You maked that check-site-meta great!
I thought it was one of top og previewer apps
And still can think it is
Maybe not popular , but great
I won't talk more about non-next.js things here
Lemme see it's cause 500 or not
Giant AngoraOP
Still not working with 200 too @alfonsüs ardani ...
export async function generateMetadata ({ params }) {
const {profeHandle} = await params
return {
title: `title is ${params.profeHandle}`,
openGraph: {
title: `og title is ${params.profeHandle}`,
},
twitter: {
title: `twitter title is ${params.profeHandle}`,
}
}
}
export default async function ProfeLayout({ params }) {
return (
<p>given parameter is {params.profeHandle}</p>
)
}Now , its interesting when i put this code in another app ( some fresh next.js , its working , but in my app directory , no... )
Also i can guess maybe some packages in node_modules are ruining everything
Whenever i test this code in a fresh next.js app , it will work
But when i install some packages like sass , styled , @supabase and some needed dependencies , and then put my main codes , it will go like this
Giant AngoraOP
Finally 😂 @alfonsüs ardani
@Giant Angora Finally 😂 <@194128415954173952>
What the helly happened
U made it gng 

Giant AngoraOP
Somehow one of sass devDependencies was preventing app for generateMetadata
Actually i dont know why
But yeah , its Next.js lmao
Giant AngoraOP
And also , a mix of 500 error cause Ldrs loaders
They drop HTMLELEMENT not defined error , but however working
