Next.js Discord

Discord Forum

[App] [Metadata] page.tsx does not overwrite layout.tsx instead 2 are delivered

Answered
Ocicat posted this in #help-forum
Open in Discord
Avatar
OcicatOP
Hey All,
Thank you for taking the time to look at this.
Before I make this into a bug report I want reach out to the community first to make sure that everything on my end is clear.

The current problem is:
Nextjs is delivering both <head> objects from layout and the page.tsx that is meant to replace / merge as stated in the docs.
title from app/layout.js is replaced by title in app/blog/page.js.
https://nextjs.org/docs/app/building-your-application/optimizing/metadata#merging
Next.js will wait for data fetching inside generateMetadata to complete before streaming UI to the client. This guarantees the first part of a streamed response includes <head> tags.
https://nextjs.org/docs/app/building-your-application/optimizing/metadata#dynamic_metadata

What is happening how ever is
I am getting metadata values from both layout and page.
(Please see the attached image.)

This is not expected behavior as metadata from layout should be replaced by page.

The code to layout and page will be added in the comments.

Thank you for you assistance.
Hope this is on my end.
Image
Answered by joulev
Remove these meta and title tags in the layout
View full answer

13 Replies

Avatar
OcicatOP
layout
//project/app/(content)/layout.tsx
import React from 'react'
import Navbar from '../components/Navbar'
import "../globals.css"
import QueryProvider from '../components/query-provider';



export const metadata = {
  title: 'Title from group content layout',
  description: 'description from group content layout',
  image: '/images/FumoLogo2.png', // Add the path to your image
  url: 'https://websitefromcontent/home', // Add your website URL
}


export default function Layout({
  children,
}: {
  children: React.ReactNode
})  {
 return (
    <html lang="en">
            <head>
        <title>{metadata.title}</title>
        <meta name="description" content={metadata.description} />
        <meta property="og:title" content={metadata.title} />
        <meta property="og:description" content={metadata.description} />
        <meta property="og:image" content={metadata.image} />
        <meta property="og:url" content={metadata.url} />
        <meta property="og:type" content="website" />
        <meta name="twitter:card" content="summary_large_image" />
        <meta name="twitter:title" content={metadata.title} />
        <meta name="twitter:description" content={metadata.description} />
        <meta name="twitter:image" content={metadata.image} />
      </head>
      <body>
        <QueryProvider>
          <div id='page'>
            <div className='z-100'>
              <Navbar />
            </div>
            {children}
          </div>
        </QueryProvider>
      </body>
    </html>
  )
}
page.tsx
//project/app/(content)/home/communities/[id]/page.tsx
import Image from 'next/image'
import Link from 'next/link'
import React from 'react'
import { HiArrowLeft } from 'react-icons/hi'
import { doc, getDoc, getFirestore } from 'firebase/firestore';
import { app } from '@/firebase';
import CommunityTag from '@/app/components/CommunityTag';
import { FaLink } from 'react-icons/fa6';
import type { Metadata as NextMetadata } from 'next';

interface Metadata extends NextMetadata {
  image: string;
  url: string;
}

interface CommunityData {
  id: string;
  timestamp: any; // Adjust the type based on your actual data structure
  tags: string;
  link: string;
  communityName: string;
  description: string;
  image: string;
  [key: string]: any; // This allows for additional properties
}

interface Props {
  params: {
    id: string;
  };
}

  return {
    title: `FUMO Society: [From page] ${communityData.communityName}`,
    description: communityData.description,
    image: communityData.image,
    url: `https://page.com/home/communities/${communityData.id}`,
    openGraph: {
      title: 'Title From Page.tsx',
      description: 'Description From Page.tsx',
      image: 'image From Page.tsx',
    },
  };
};

export default async function CommunityPage({ params }: Props ) {
  const db = getFirestore(app);
  const querySnapshot = await getDoc(doc(db, 'communities', params.id));
  const data = { ...querySnapshot.data(), id: querySnapshot.id } as CommunityData;

  return (...)
}
Avatar
Remove these meta and title tags in the layout
Answer
Avatar
Correct, your exporting the metadata here:

export const metadata = {
  title: 'Title from group content layout',
  description: 'description from group content layout',
  image: '/images/FumoLogo2.png', // Add the path to your image
  url: 'https://websitefromcontent/home', // Add your website URL
}


Then your setting it in the head, you dont need to do that, it will do it for you, thats the point of exporting the metadata.
Sorry meant to respond to this to give reinforcement to what joulev said.
Avatar
OcicatOP
@Jboncz
Thank you both.
Didn't realize it was that easy.
Avatar
Yeah essentially you were just telling nextjs to do it... but also doing it yourself 😄 Happens to the best of us
Avatar
OcicatOP
Just one more thing.
Why isn't image working?
Its not getting applied for opengraph?
Avatar
Not familiar enough with opengraph to understand what your trying to accomplish. Are you just supplying a URL to the image?
Avatar
OcicatOP
I've updated the things.
In layout
export const metadata = {
  title: 'FUMO Society',
  description: '(ᗜˬᗜ)',
  image: '/images/FumoLogo2.png', // Add the path to your image
  url: 'https://website.com/home/', // Add your website URL
  openGraph: {
    title: 'FUMO Society',
    description: '(ᗜˬᗜ)',
    image: '/images/FumoLogo2.png', // Add the path to your image
  },
  twitter: {
    image: '/images/FumoLogo2.png',
  }
}

And even there image is not embeding.
Avatar
I have never tried putting and image in my metadata.... lol not sure, maybe open another help-forum post.
Avatar
OcicatOP
Yeah I can do it the old way with importing the head - meta tag
This becomes a problem when dynamic images are introduced.
But yeah thank you.