【问题标题】:How to force Nextjs to read head tags如何强制 Nextjs 读取头部标签
【发布时间】:2022-11-14 08:19:21
【问题描述】:

我的 nextjs 应用程序(使用 react v18)的 _app.tsx 和 _document.tsx 页面中都有 head 标签。

我无法使用保存在这些 Head 标记中的标题或网站图标更新浏览器选项卡。

在 app.tsx 我有:

<>
      <Head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
        <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
        <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/>
        <link rel="manifest" href="/site.webmanifest"></link>
      </Head>
    
      <ChakraProvider theme={theme}>
        <ApolloProvider client={apolloClient}>{getLayout(<Component {...pageProps} />)}</ApolloProvider>
      </ChakraProvider>
    </>

在 _document.tsx 我有:

  <Html lang="en">
        <Head>
          <meta name="theme-color" key="theme-color" content="#000000" />
          <meta name="description" content="this is my description" key="description" />
          <meta property="og:title" content="i expect to see this in the browser tab" key="title" />
          <meta property="og:description" content="can't get these tags to populate" key="og:description" />
          <link rel="preconnect" href="https://fonts.googleapis.com" />
          <link rel="preconnect" href="https://fonts.gstatic.com"  />
          <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;700&family=Poppins:wght@300;400;600&family=Kristi&display=swap" rel="stylesheet" />
        </Head>

我该怎么做才能强制 nextjs 读取我的头部标签?

我尝试将所有这些添加到 _document.tsx 文件中:

<link rel="apple-touch-icon" sizes="180x180" href="/public/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
          <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
          <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
          <link rel="icon" href="/favicon.ico" />

我将文件命名为每个保存在公用文件夹中。

【问题讨论】:

  • 您在浏览器的选项卡中看到什么标题?您是否尝试过从_document 中删除元标记并将它们移至_app
  • 我看到 localhost 3000/[后跟页面路径]
  • 如果我将 head 标签添加到布局组件,我可以使标题出现在浏览器选项卡中,但这对 favicon 没有帮助,我不想在每个布局上都这样做 - 我只想要他相同的 favicon和每一页的标题
  • 除了其他图标链接之外,还尝试添加&lt;link rel="shortcut icon" href="/favicon.ico" /&gt;(确保favicon.ico 存在于您的public 文件夹中)。
  • 您的建议与我一直在尝试的不同之处在于“rel”属性中包含“快捷方式”一词。我尝试添加该词,但仍然遇到同样的问题 - 详细信息未填充在浏览器选项卡中

标签: reactjs next.js http-headers


【解决方案1】:

使用 next/head,您可以将 head 标签放在您编写类似功能组件的页面中

import React from "react";
import Head from 'next/head';

const MyPage = () => {
  return (
    <>
      <Head>
        <title>Why us</title>
        <link rel="icon" href="/logo192.png" />
      </Head>
    </>
  )
}

export default MyPage;

通用解决方案的更新

头部组件

import React from 'react';
import NextHead from 'next/head';

const Head = ({ title, description }) => (
  <NextHead>
    <meta charSet="UTF-8" />
    <title>{title || ''}</title>
    <link rel="icon" href="/favicon.ico" />  {/* icon image */}
    <meta name="description" content={description || ''} />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <link rel="apple-touch-icon" href="/logo192.png" />
    <link rel="manifest" href="/manifest.json" />
  </NextHead>
);

export default Head;

我们在 layout.tsx 中使用 Head 组件

const Layout = ({ children }) => {
  return(
    <>
      <Head title="Generic Title" description="Generic Title" />
      <div id="layout-wrapper">
        <Header /> {/*your header component*/}
        <main>
          <Sidebar /> {/*your sidebar component*/}
          <div className="main-content">{children}</div>
        </main>
        <Footer /> {/*your footer component*/}
      </div>
    </>
  )
}

现在我们在 _app.js 中使用 Layout 组件

const App = ({ Component, pageProps }) => {

  return(
    <Provider store={store}>
      <Layout>
        <div className="page-content">
          <Component {...pageProps} />
        </div>
      </Layout>
    </Provider>
  )

}

页面特定标题方法的更新

_app.js

import { NextSeo } from "next-seo";

const App = ({ Component, pageProps }) => {

  return(
    <Provider store={store}>
      <Layout>
        <div className="page-content">
          <NextSeo
            defaultTitle="Generic Title"
            title={pageProps && pageProps.title ? pageProps.title : ""}
          />
          <Component {...pageProps} />
        </div>
      </Layout>
    </Provider>
  )

}

示例页面

import { GetServerSideProps } from 'next';

const Example = () => {
}

export const getServerSideProps: GetServerSideProps = async (ctx) => {
  return {
    props: {
      title: 'Example Page'
    },
  };
};

最后更新

您还可以为您的应用使用 Head 标签,如下所示

import Head from 'next/head'

function App({ Component, pageProps }) {
  return (
    <>
      <Head>
        <title>My Next App</title>
        <meta name='description' content='This is a desription for My Next App'/>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <Component {...pageProps} />
    </>
  )
}

export default App

【讨论】:

  • 嗨@Ahmet你是说我的错误是从下一个/头导入Head而不是NextHead吗?你是说如果 app.tsx 和 document.tsx 文件中包含 nextjs 就不会使用 head 标签?我看不到 favicon 如何从布局文件中工作。你确定这就是你的意思吗?
  • 您是否从 _document.tsx 中的 'next/document/ 导入 Head ?
  • 否 - 导入语句在 app.tsx 中。 _document.tsx 有一个从 next/document 导入的 Head 语句
  • 无论哪种方式,我都尝试了您的一般建议 - 谷歌字体必须在 _document head 语句中,但即使如此,我仍然无法从单独的 NextHead 组件中获取其余部分。您是否知道任何解释如何强制在下一个 js 应用程序中应用 head 标签的文档或教程?
  • 我上次更新了我的答案,也许现在可以了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-02
  • 1970-01-01
  • 2012-10-10
  • 1970-01-01
  • 2019-05-08
相关资源
最近更新 更多