Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meta tags are moving to <body> tag instead of <head> tag

In my NextJS project, I use the generateMetadata() function in page.js files. At first refresh, the meta tags are stored in correctly but after some navigation through pages, they are in tags? I tried fetch instead of axios and set cache:'no store' and tried next :{revalidate: 0} but even after some navigations sometimes it's working correctly, and sometimes it's not

navigation is client component

import axios from "axios";
import AddDynamicForm from "../components/FormAdding/Dynamicform";
import getmetaTags from "../lib/getMeta";


// return await getmetaTags('about','About Us')
export async function generateMetadata() {
    try{
        const headersList =await headers();
        
        const host = headersList.get('x-forwarded-host') || headersList.get('host');
        const proto = headersList.get('x-forwarded-proto') ||
        (process.env.NODE_ENV === 'development' ? 'http' : 'https');
        const protocol = proto.split(',')[0];
        const path = headersList.get('x-invoke-path') || '';
        const currentURL = `${protocol}://${host}${path}`;
        
        const res = await fetch(`${process.env.NEXT_PUBLIC_URL}/api/about`,{
            method :'GET',
            headers: {
                'Content-Type': 'application/json'
            },
            next :{revalidate : 0}
        });
        
        if (!res.ok) {
            throw new Error("Error occured");
        }
        
        let data = await res.json()
        if (res.data?.isFind === true) {
            data = res.data.data;
        }
        
        return {
            title: data?.title_tag || `About Us` ,
            description: data?.meta_description || ` About Us Content` ,
            keywords: data?.meta_keyword || `About Us` ,
            url: data?.url || currentURL,
            authors: [
                {
                    name: data?.url || currentURL,
                    url: data?.url || currentURL
                }
            ],
            
            openGraph: {
                title: data?.title_tag ||  `About Us` ,
                description: data?.meta_description || `About Us Content` ,
                url: data?.url || currentURL,
                
                siteName: 'Sell My Product Online',
                locale: 'en',
                type: 'website',
            },
            
            twitter: {
                card: 'summary',
                title: data?.title_tag ||  `About Us` ,
                description: data?.meta_description || `About Us Content` ,
            },
        }
    }
    
    catch(e){
        console.log(e);
        return {
            title: `About Us` ,
            description: 'About Us Content',
            keywords:  `About Us` ,
            openGraph: {
                title:  `About Us` ,
                description:`About Us Content` ,
                
                siteName: 'Sell My Product Online',
                locale: 'en',
                type: 'website',
            },
            
            twitter: {
                card: 'summary',
                title:  `About Us` ,
                description: `About Us Content` ,
            },
        }
    }
}


async function fetchData() {
    try {
        const res = await axios.get(`${process.env.NEXT_PUBLIC_URL}/api/about`);
        if (!res) {
            throw new Error("Error occured");
        }
        
        let data;
        if (res.data?.isFind === true) {
            data = res.data.data
        }
        return data
    }
    catch (e) {
        console.log("Error occured", e)
    }
}


export default async function AboutPage() {
    const data = await fetchData();
    const htmlTags = data.html
    
    return (
        <AddDynamicForm data={htmlTags} />
    )
}

like image 756
Vignesh Avatar asked Oct 19 '25 19:10

Vignesh


2 Answers

This is not an issue for production builds so it should be okay. It seems to be an unfixed bug that only occurs during development. When running a production build via next build, the metadata is correctly inside the head tag.

You can verify this by checking the index file: .next/server/app/index.html, which is generated after a production build.

Extra Information

I encountered this without using <Suspense> or generateMetadata(), so I expect it is a broader problem than what is discussed on the GitHub issue

like image 146
Nick4814 Avatar answered Oct 27 '25 07:10

Nick4814


Update the nextJS and add these lines inside next.config.mjs

  htmlLimitedBots: /.*/,

hope this problem will be clear if anyone faces that problem(meta tags in body instead of head)

But I advise you not to add these lines.

By default, Next.js allows some bots and crawlers.

When those crawlers and bots crawl the page, Next.js gives the complete page with the correct meta inside the head tag. Here, those bots are allowed by default.

  /Mediapartners-Google|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti/i
like image 42
Usman Haider Avatar answered Oct 27 '25 05:10

Usman Haider



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!