在我的Next.js应用程序中,我试图在产品页面上插入具有动态内容的og meta tags
。所以meta tags
的内容将根据从服务器获取的产品数据而改变。
我使用getServerSideProps
获取产品数据,并将产品数据作为props
传递给页面组件。
export const getServerSideProps = wrapper.getServerSideProps(
store => async (context) => {
const response = await fetch(url, {
method: 'GET',
});
const data = await response.json();
return {
props: {
host: context.req.headers.host,
product: data.product
}
}
}
)
第一种方法
我尝试在<Head>
组件中的产品页面组件上直接插入meta tags
。这里meta tags
即使有静态conetnt也不会显示在页面源中。
const Product = ({product}) => {
return (
product ?
<>
<Head>
<title>{product.title}</title>
<meta name="description"
content={product.description}/>
<meta property="og:title" content={product.title}/>
<meta property="og:type" content="video.movie"/>
<meta property="og:url" content={`${props.host}/products/${product.slug}`}/>
<meta property="og:description" content={product.description}/>
<meta property="og:image" content={product.thumbnail}/>
</Head>
<Course/>
</> : null
);
};
第二种方法
return (
<Html lang="en">
<Head>
{/*<meta property="og:image" content="https://static.onlinevideobooks.com/abed1e5658b3ad23c38c22646968e4f2/files/media/images/2022/04/5b0645b9-ab03-4233-b5f3-86b092d4062b/conversions/cad47d2beb9143eab3d65ea4a75b0b0e-1280x720.webp" />*/}
{/*<title>your keyword rich title of the website and/or webpage</title>*/}
<meta name="description"
content="description of your website/webpage, make sure you use keywords!"/>
<meta property="og:title" content="short title of your website/webpage"/>
<meta property="og:type" content="video.movie"/>
<meta property="og:url" content="https://example.com/"/>
<meta property="og:description" content="description of your website/webpage"/>
<meta property="og:image"
content="https://example.com/image"/>
</Head>
</Html>
);
我尝试在_document.js
文件的<Head>
中插入meta tags
。这里我只传递静态conetnt,因为我在_document.js
中没有动态数据。这一次meta tags
出现在页面源中,我也可以在facebook上预览它们。
第三种方法
然后,当我在该组件中接收到pageProps
时,我尝试在_app.js
文件中插入这些标记。不幸的是,当我像第一种方法一样用meta tags
传递动态内容时,它们不会显示在页面源中,但当我像第二种方法一样传递静态内容时,会显示出来。
完整_app.js代码要点
更新
关于我的第三种方法,我再次检查了一遍,令人惊讶的是,当在_app.js
中插入静态或动态内容时,我可以在页面源中看到所有meta tags
。当内容是静态的,我可以预览url,但当内容是动态的,我不能使用Facebook调试或Open graph 预览url
My Next.js版本为12.2.0
您的_app.js
中的代码可能阻止了元标记的呈现。";查看页面源";在浏览器中,不会等待客户端代码完成渲染。您可以对此进行验证,然后单击";查看页面源";从您的浏览器。你看到你期望的HTML了吗?例如,你看到你的元标签和产品HTML了吗?
我预计,除了一些静态HTML标记之外,您可能什么都看不到。您可以尝试的一件事是将钩子和渲染逻辑的使用向下移动到它自己的MainLayout
组件中。
然后,您可以尝试第一种方法,执行以下操作:
const Product = ({product}) => {
return (
product ?
<>
<Head>
<title>{product.title}</title>
<meta name="description"
content={product.description}/>
<meta property="og:title" content={product.title}/>
<meta property="og:type" content="video.movie"/>
<meta property="og:url" content={`${props.host}/products/${product.slug}`}/>
<meta property="og:description" content={product.description}/>
<meta property="og:image" content={product.thumbnail}/>
</Head>
<MainLayout>
<Course/>
<MainLayout>
</> : null
);
};
其中MainLayout
包含_app.js
中的所有逻辑。这将使您的实际_app.js
没有任何阻止元标记呈现的客户端代码。
基本上,我们希望利用Next.js静态优化,并让它为您的页面预呈现元标签,这样浏览器和网络爬虫就可以在不等待任何客户端渲染的情况下获得数据。
希望这能帮助到一些人,但我的问题是<Head>
标签在_app.js
中的位置。出于某种原因,当它嵌套在<Auth0ProviderWithHistory>
下时,元标记不会呈现,将它移到它之外给了我胜利。
损坏
<Auth0ProviderWithHistory>
<Head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
{openGraphData.map((og) => (
<meta {...og} />
))}
<title>{pageProps.title}</title>
</Head>
<CssBaseline>
<div className="page-layout">
<NavBar />
<Component {...pageProps} />
<Footer />
</div>
</CssBaseline>
</Auth0ProviderWithHistory>
固定
<span>
<Head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
{openGraphData.map((og) => (
<meta {...og} />
))}
<title>{pageProps.title}</title>
</Head>
<Auth0ProviderWithHistory>
<CssBaseline>
<div className="page-layout">
<NavBar />
<Component {...pageProps} />
<Footer />
</div>
</CssBaseline>
</Auth0ProviderWithHistory>
</span>
不确定引擎盖下发生了什么,但删除Head
标签可以解决这个问题。
我只是把我的元标签放在Head
中,没有嵌套它们,它就起作用了。