Search code examples
next.jsmaterial-uimetadataemotion

Issue with Metadata Changes in Next.js: Metadata Overwritten After .next Folder Rebuild


I'm encountering an issue with metadata customization in my Next.js application. Although I'm able to successfully modify the metadata in my layout.tsx file, the changes are not reflecting in the console output. Additionally, I've noticed that after deleting the .next folder and rebuilding, the metadata is overwritten.

Below is the relevant code snippet from my layout.tsx file:

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: {
    default: "Love Coding? Master Web Dev with Forge Code: Python, Next.js, FastAPI, Deployment & More!",
    template: "%s | Forge Code"
  },
  description: "**Learn to code like a pro!** Master Python, Next.js, FastAPI, deployment strategies, **SOLID principles**, and **system design**. Build real-world web applications and **unleash your coding potential** with Forge Code. We'll guide you every step of the way!",
  keywords: [
    "web development",
    "coding",
    // Other keywords...
  ]
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <div>
          Hello 
        </div>
        {children}
      </body>
    </html>
  );
}

Project Directory Structure:

├── app
│   ├── favicon.ico
│   ├── globals.css
│   └── layout.tsx
├── ... (other directories and files)

Observations: After deleting the .next folder and rebuilding, I can see my metadata changes, but I'm unable to access my app. Upon rebuilding, the metadata gets overwritten, leading to the loss of my customizations. Expected Behavior: I expect my metadata changes to be reflected consistently throughout the application without being overwritten during the build process. This is ss of overwritten metadata

This is the expected metadata

Additional Context: I'm using Emotion , material -ui for styling in my project. This issue is hindering my progress, and any insights or guidance on resolving it would be greatly appreciated. Screenshot: Metadata Overwritten Screenshot

Posting this question on Stack Overflow should help you receive assistance and insights from the community to resolve your metadata customization issue in Next.js.

I want to customized my metadata in next js project.


Solution

  • Problem :

    Metadata is overwritten

    I noticed that my homepage metadata works perfectly when it's in page.tsx within the app directory. However, when I use index.tsx from the pages folder, the metadata doesn't render correctly.

    Possible Cause :

    • Metadata written in layout gets overwritten by current page's metadata.
    • In app router there is no index.js according to app router file conventions. Don't mix file conventions.

    Please Read :

    Possible Solution :

    • Move the layout's metadata in Home page (page.js located at root level), & for other pages set metadata in their respective pages. This is because NextJs replaces duplicate metadata keys Read this 1.

    • In layout.js only keep metadata that doesn't changes (Read this 5) or just don't put any metadata in layout.js keep metadata in their own pages.

    Small Demonstration to show overwriting of metadata :

    Folder Structure :

    app
    ├── about
    │   └── page.js   // about page
    ├── favicon.ico
    ├── globals.css
    ├── layout.js
    └── page.js   // home page
    

    layout.js :

    import { Inter } from "next/font/google";
    import "./globals.css";
    
    const inter = Inter({ subsets: ["latin"] });
    
    export const metadata = {
      title: "MetaData from Layout",
      description: "MetaData from Layout",
    };
    
    export default function RootLayout({ children }) {
      return (
        <html lang="en">
          <body className={inter.className}>{children}</body>
        </html>
      );
    }
    

    page.js at src\app\page.js :

    import Image from "next/image";
    // export const metadata = {
    //   title: "MetaData from HomePage",
    //   description: "MetaData from HomePage",
    // };
    
    // NOW HOMEPAGE SHOWS METADATA FROM layout.js
    
    // UNCOMMENT & SEE
    
    export default function Home() {
      return (
        <div>
          Homepage
        </div>
      );
    }
    

    about page at src\app\about\page.js :

    export const metadata = {
        title: "MetaData from About",
        description: "MetaData from About",
    };
    
     // THIS WILL NOT GET OVERWRITTEN
    
    export default function AboutPg() {
        return (
            <div>
                About
            </div>
        );
    }
    

    If you have any doubts, then please leave a comment (I will update answer if necessary)