简体   繁体   English

如何在 next.js 部分创建动态标题?

[英]How can I create dynamic titles in next.js <head> section?

I have a fully functioning website but the head sections doesn't retrieve page specific <title> and <meta description> .我有一个功能齐全的网站,但头部部分没有检索特定于页面的<title><meta description>

For example, if I'm on the about page, with the title tag "About me" I would like to have "About me" rendered in the <title> tag.例如,如果我在关于页面上,标题标签为“关于我”,我想在<title>标签中呈现“关于我”。 What I basically need is to load props, vars or something similar in my Head component that consist of an actual title and description.我基本上需要的是在我的 Head 组件中加载由实际标题和描述组成的道具、变量或类似内容。 I've already read about some examples in the official documentation but there are no examples with updating the head with dynamic data.我已经在官方文档中阅读了一些示例,但是没有使用动态数据更新头部的示例。

This is the current code of my component:这是我的组件的当前代码:

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

const Head = ({ title, description }) => (
    <NextHead>
        <meta charSet="UTF-8" />
        <title>My Website{title}</title>
        <meta name="description" content={description || ''} />
        <meta name="viewport" content="width=device-width, initial-scale=1" key="viewport" />
    </NextHead>
);

I've created a Layout.js component for the posts and pages.我为帖子和页面创建了一个 Layout.js 组件。 The <Head> I described earlier is imported in the layout component.我之前描述的<Head>是在布局组件中导入的。

import React from 'react';
import Head from '../components/Head';


export default ({ children, as, settings = {}, title="default text" }) => (
    <main>
        <Head>
            <title>{title}</title>
        </Head>
        <div className="app__container">
            <div className="row">{children}</div>
        </div>
    </main>
);

I expected that when I'm for example at /work/great-client I would see an updated <title> tag with great-client我预计当我在/work/great-client时,我会看到一个更新的<title>标签和great-client

I found this solution a bit simpler and with fewer lines of code.我发现这个解决方案有点简单,代码行也更少。

_app.js: _app.js:

  export default function MyApp({ Component, pageProps }) {
  return (
    <>
      <Head>
        <title>{Component.title}</title>        
      </Head>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </>
  );
}

Home.js:主页.js:

Home.title = 'Homepage';
export default function Home() {
  return (
    <>
      /* Some code */
    </>
  );
}

It should be:它应该是:

import React from 'react';
import Head from '../components/Head';

export default ({ children, as, settings = {}, title="default text" }) => (
    <main>
        <Head title={title}>
        <div className="app__container">
            <div className="row">{children}</div>
        </div>
    </main>
);

If you want to use it as children of Head, then you have to modify your Head component:如果要将其用作 Head 的子级,则必须修改 Head 组件:

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

const Head = ({ title, description, children }) => (
    <NextHead>
        <meta charSet="UTF-8" />
        {children}
        <meta name="description" content={description || ''} />
        <meta name="viewport" content="width=device-width, initial-scale=1" key="viewport" />
    </NextHead>
);

I got it working after trying a little more with the second example.在尝试了第二个示例之后,我得到了它的工作。

Little bit more explanation follows in the code below.下面的代码中有更多解释。

Below example code shows Post.js including a shared component <Layout> .下面的示例代码显示了包含共享组件<Layout>的 Post.js。 In layout i've added and added {props.meta.title} .在布局中,我添加并添加了{props.meta.title} Now its possible to retrieve dynamic title tags for page/post specific.现在可以检索页面/帖子特定的动态标题标签。

const Post = props => {
    const {
        content,
        meta: { title },
    } = props;


    return (
        <Layout>
            <Head>
                <title>{props.meta.title}</title>
            </Head>
            <div className="post">
                <div className="content-inner">
                        <h1>{title}</h1>
                    <article dangerouslySetInnerHTML={{ __html: content }} />
                </div>
            </div>
        </Layout>
    );
};

Post.getInitialProps = function(reqOrContext) {
    const { slug } = reqOrContext.query;
    let content = require(`../work/${slug}.md`);
    const converter = new Converter({ metadata: true });
    content = converter.makeHtml(content);
    const meta = converter.getMetadata();
    return { content, meta };
};

export default withRouter(Post);
  1. Create a layout component创建布局组件

  2. Destructure children from props从道具中解构孩子

  3. Add to title {children.type.name}添加到标题 {children.type.name}

     console.log(children); return ( <> <Head> <title>{children.type.name.toLowerCase()}</title> </Head> <div className="layout">{children}</div> </> ); };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM