[▲ Vercel Community](/) · [Categories](/categories) · [Latest](/latest) · [Top](/top) · [Live](/live) [Help](/c/help/9) # Dynmic Metadata from API Appears Inside <body> Instead of <head> (App) 167 views · 5 likes · 11 posts Akash Electron (@akash-electron) · 2025-11-20 I am using **Next.js App Router** (`app/`) with **dynamic routes** and generating metadata based on API responses. However, my metadata **does NOT appear in the SSR `<head>`** when I check “View Page Source”. Instead, metadata is **either missing**, or appears **inside the `<body>`** after hydration. ## **Project Context** * Route: `/app/(propertyPages)/(SeoPages)/[...slugs]/page.tsx` * Metadata is generated using `generateMetadata()` * Metadata depends on API calls (example: `getPageBySlugOne`, `validateSlugsOne`, etc.) * I am using: ``` export const revalidate = 86400; // ISR 24h export const dynamicParams = true; // Enable on-demand generation ``` * API functions run inside `generateMetadata()` ## **The Problem** Even though metadata is returned correctly from `generateMetadata`, it **does not show** inside `<head>` in SSR HTML. ### What I actually see in “View Page Source”: * Only global metadata from `layout.tsx` * NO title * NO meta description * NOTHING from `generateMetadata()` ### Instead, Next.js injects metadata **after hydration** inside the `<body>` This is the HTML output I uploaded: (uploaded exact file here: **`random.txt`**) All metadata is missing from `<head>` in the raw server HTML. ### How can I force metadata to be rendered **server-side inside `<head>`** even when it comes from an API? ### 3. Does ISR + dynamicParams still make `generateMetadata()` behave dynamically? ### 4. Do I need to use `cache()`, `dynamic = "force-static"`, or `{ next: { revalidate }}` inside fetch() to fix this? Akash Electron (@akash-electron) · 2025-11-20 @harpreet-3932 @amyegan I hope you can help me out with this issue 🙏 Akash Electron (@akash-electron) · 2025-11-20 @pawlean @harpreet-3932 @emil-christensen Amy Egan (@amyegan) · 2025-11-20 · ♥ 1 The Next.js team have said that this is intentional when [streaming metadata](https://nextjs.org/docs/app/api-reference/functions/generate-metadata#streaming-metadata) is involved https://github.com/vercel/next.js/issues/79313#issuecomment-2892288965 > whenever metadata resolution would potentially block rendering the page, we instead defer it and stream it into the page body. Browsers are still able to interpret the `title` tag properly regardless of where it's rendered in the DOM I hope that helps! farzigalib (@farzigalib) · 2025-11-21 · ♥ 2 Recently I worked on same scenario, check out the below code in your page.tsx ```javascript /app/(propertyPages)/(SeoPages)/[...slugs]/page.tsx interface PageProps { params: Promise<{ slug: string }>; } export async function generateMetadata({ params, }: PageProps): Promise<Metadata> { const { slug } = await params; const workPreview = await getWorkPreviewAPI({ type: 'slug', id: slug }); if (!workPreview.success) { return {}; } const { metaTitle, metaDescription, metaKeywords, metaOGImg, metaAltText, bannerImage, } = workPreview.blogData; return { title: metaTitle, description: metaDescription, keywords: metaKeywords, openGraph: { title: metaTitle, description: metaDescription, images: { url: getImageUrl(metaOGImg ?? bannerImage), alt: metaAltText ?? '', }, }, twitter: { title: metaTitle, description: metaDescription, images: { url: getImageUrl(metaOGImg ?? bannerImage), alt: metaAltText ?? '', }, card: 'summary_large_image', }, }; } ``` On local you might be not get expected result but if make it like it will work as expected. Pauline P. Narvas (@pawlean) · 2025-11-21 · ♥ 1 @farzigalib Thanks for sharing what worked for you :slight_smile: Akash Electron (@akash-electron) · 2025-11-21 thanks for replying , but i am doiing the same farzigalib (@farzigalib) · 2025-11-21 I would help you if you provide more context of you code, specially layout.tsx and \[…slug\]/page.tsx farzigalib (@farzigalib) · 2025-11-21 I implemented the same in one of my project you can check it [here](https://www.systango.com/case-studies/3t) So basically /case-studies/\[slug\] is dynamic and every page have it own metadata Akash Electron (@akash-electron) · 2025-11-22 actually problem is in only this url , else dynamic route are woring fine as expectd farzigalib (@farzigalib) · 2025-11-24 · ♥ 1 Create layout.tsx for `(SeoPages)` & `(propertyPages)` and then it will work. Try once.