next.js 页面源中缺少页面的 meta标记

j0pj023g  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(123)

我的Portfolio网站有一个基于Nextjs的Web应用程序,我在_document.jsx文件中定义了一些常见的 meta标记,并且有一些静态页面,在浏览器选项卡中可以看到标题,但当我打开Page Source时,这些标题却不见了。
我的_document.jsx文件代码如下:

// Next
import Document, { Html, Head, Main, NextScript } from 'next/document';
import Script from 'next/script';

// styled-components
import { ServerStyleSheet } from 'styled-components';

const APP_NAME = `Dhaval Vira Resume | CV | Portfolio`;
const APP_DESC = `A skilled full-stack developer who has worked on projects ranging from small personal sites to large enterprise systems.`;
const APP_URL = `https://dhavalvira.com`;

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (Component) => (props) =>
            sheet.collectStyles(<Component {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: [initialProps.styles, sheet.getStyleElement()],
      };
    } finally {
      sheet.seal();
    }
  }

  render() {
    return (
      <Html lang='en-US'>
        <Head>
          {/* General Meta Tags */}
          <meta charSet='utf-8' />
          <meta httpEquiv='X-UA-Compatible' content='IE=edge' />
          <link rel='icon' href='/favicon.ico' />

          {/* Meta Tags */}
          <meta name='application-name' content={APP_NAME} />
          <meta name='description' content={APP_DESC} />
          <meta name='author' content='Dhaval Vira' />
          <meta name='robots' content='index, follow' />
          <meta name='rating' content='general' />
          <link rel='canonical' href={APP_URL} />
          <meta httpEquiv='Content-Type' content='text/html; charset=utf-8' />
          <meta name='language' content='English' />
          <meta name='revisit-after' content='1 day' />
          <meta name='creationdate' content='14-Feb-2022' />
          <meta name='distribution' content='global' />
          <meta
            name='keywords'
            content='CV, resume, online cv, online resume, professional resume, portfolio, next js developer, nextjs developer, freelance developer, full stack developer, full-stack developer, freelance full stack developer, freelance full-stack developer, freelance next js developer, freelance next.js developer, freelance nextjs developer'
          />

          {/* Open Graph */}
          <meta property='og:url' content={APP_URL} />
          <meta property='og:type' content='website' />
          <meta property='og:title' content={APP_NAME} />
          <meta property='og:description' content={APP_DESC} />
          <meta property='og:image' content='/D_V_Cropped.png' />

          {/* Twitter Meta Tags */}
          <meta name='twitter:card' content='summary_large_image' />
          <meta property='twitter:domain' content={APP_URL} />
          <meta property='twitter:url' content={APP_URL} />
          <meta name='twitter:title' content={APP_NAME} />
          <meta name='twitter:description' content={APP_DESC} />
          <meta name='twitter:image' content='/D_V_Cropped.png' />

          {/* Some Extra Tags */}
          <meta name='apple-mobile-web-app-capable' content='yes' />
          <meta
            name='apple-mobile-web-app-status-bar-style'
            content='default'
          />
          <meta name='apple-mobile-web-app-title' content={APP_NAME} />
          <meta name='description' content={APP_DESC} />
          <meta name='format-detection' content='telephone=no' />
          <meta name='mobile-web-app-capable' content='yes' />
          <meta name='theme-color' content='#000000' />
          <link rel='manifest' href='/manifest.json' />
          <link rel='apple-touch-icon' href='/D_V_Cropped.png' />

          {/* Icons */}
          <link
            rel='apple-touch-icon'
            sizes='57x57'
            href='/icons/apple-icon-57x57.png'
          />
          <link
            rel='apple-touch-icon'
            sizes='60x60'
            href='/icons/apple-icon-60x60.png'
          />
          <link
            rel='apple-touch-icon'
            sizes='72x72'
            href='/icons/apple-icon-72x72.png'
          />
          <link
            rel='apple-touch-icon'
            sizes='76x76'
            href='/icons/apple-icon-76x76.png'
          />
          <link
            rel='apple-touch-icon'
            sizes='114x114'
            href='/icons/apple-icon-114x114.png'
          />
          <link
            rel='apple-touch-icon'
            sizes='120x120'
            href='/icons/apple-icon-120x120.png'
          />
          <link
            rel='apple-touch-icon'
            sizes='144x144'
            href='/icons/apple-icon-144x144.png'
          />
          <link
            rel='apple-touch-icon'
            sizes='152x152'
            href='/icons/apple-icon-152x152.png'
          />
          <link
            rel='apple-touch-icon'
            sizes='180x180'
            href='/icons/apple-icon-180x180.png'
          />
          <link
            rel='apple-touch-icon'
            sizes='192x192'
            href='/icons/apple-icon-precomposed.png'
          />
          <link
            rel='icon'
            type='image/png'
            sizes='192x192'
            href='/icons/android-icon-192x192.png'
          />
          <link
            rel='icon'
            type='image/png'
            sizes='32x32'
            href='/icons/favicon-32x32.png'
          />
          <link
            rel='icon'
            type='image/png'
            sizes='96x96'
            href='/icons/favicon-96x96.png'
          />
          <link
            rel='icon'
            type='image/png'
            sizes='16x16'
            href='/icons/favicon-16x16.png'
          />
          <meta name='msapplication-TileColor' content='#54ca95' />
          <meta name='msapplication-TileImage' content='/ms-icon-144x144.png' />
          <meta name='msapplication-TileImage' content='/ms-icon-150x150.png' />
          <meta name='msapplication-TileImage' content='/ms-icon-310x310.png' />
          <meta name='theme-color' content='#54ca95' />

          {/* Google Tag Manager */}
          // GTM iFrame Tag

          {/* LinkedIn Insight Tags */}
          // LinkedIn Insight Scrip Tags

          {/* Google Tag Manager */}
          // Google Tag Manager Script Tag
          </Script>

          {/* Schema.org */}
          // Schema.org Script Tag
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

下面的代码来自blogs.jsx,其中<Head></Head>标签内的标题仍然是静态的<Head><title>Blog :: Dhaval Vira Resume</title></Head>。这个标题在Chrome选项卡中可见,但当我打开页面源代码时,它却不见了。
下面是来自pages/blog/[index].js页面的代码,当我打开下面的页面源代码时-所有这些 meta标记都丢失了。

const BlogPost = (props) => {
  const router = useRouter();

  useEffect(() => {
    Prism.highlightAll();
  }, []);

  // destructuring props
  const { singleData, ...other } = props;

  return (
    <Fragment>
      <Head>
        <title>{singleData[0].blogTitle} :: Dhaval Vira Resume</title>
        <meta name='description' content={singleData[0].seoDescription} />
        <meta name='keywords' content={singleData[0].tags.map((tag) => tag)} />

        {/* OG Meta Tags */}
        <meta property='og:title' content={singleData[0].seoTitle} />
        <meta
          property='og:description'
          content={singleData[0].seoDescription}
        />
        <meta property='og:type' content='article' />
        <meta
          property='og:url'
          content={`${process.env.SHARE_URL}${router.asPath}`}
        />
        <meta
          name='image'
          property='og:image'
          content={singleData[0].displayImageUrl}
        />

        {/* Twitter Meta Tags */}
        <meta property='twitter:title' content={singleData[0].seoTitle} />
        <meta
          property='twitter:description'
          content={singleData[0].seoDescription}
        />
        <meta
          property='twitter:image'
          content={singleData[0].displayImageUrl}
        />
        <link
          rel='canonical'
          href={`${process.env.SHARE_URL}${router.asPath}`}
        />
      </Head>

      <div>{/* HTML Code goes here */}</div>
    </Fragment>
  );
};

export default BlogPost;

export const getServerSideProps = async (context) => {
  const { index } = context.params;

  const response = await axios({
    url: `${process.env.SERVER_URL}/api/get-single-blog-detail?slug=${index}`,
    method: 'GET',
    validateStatus: function (status) {
      return status >= 200 && status < 599;
    },
  });

  switch (response.status) {
    case 200:
      return {
        props: {
          singleData: response.data.comments,
        },
      };
    case 500:
      return {
        redirect: {
          destination: '/500',
          permanent: false,
        },
      };
    default:
      return {
        redirect: {
          destination: '/404',
          permanent: false,
        },
      };
  }
};

此外,如果我分享我的投资组合网站的链接与任何人(WhatsApp或LinkedIn)在那个地方也当标题来了,它来自静态页面或动态页面,它来自_document.jsx文件。
下面是_app.jsx代码:

// React
import React, { Fragment, useEffect, useState } from 'react';

// next component
import Head from 'next/head';
import Router from 'next/router';

// Preloader Component
import Loader from '../Loader/loader';

// react-hot-toast
import { Toaster } from 'react-hot-toast';

// NProgress Package & CSS
import NProgress from 'nprogress';
import '../styles/nprogress.css';

Router.events.on('routeChangeStart', NProgress.start);
Router.events.on('routeChangeError', NProgress.done);
Router.events.on('routeChangeComplete', NProgress.done);

import '../styles/globals.css';

// Google Firebase - Analytics - SDK
import { getAnalytics, logEvent } from 'firebase/analytics';

// Utils Func for Firebase
import { app } from '../utils/firebase';

function MyApp(props) {
  const { Component, pageProps } = props;

  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      setLoading(false);
    }, 4000);
  }, []);

  if (loading) {
    return (
      <Fragment>
        <Head>
          <title>Dhaval Vira Resume</title>
          <meta
            name='description'
            content='online resume website of Dhaval Vira, cv of Dhaval Vira, portfolio of Dhaval Vira'
          />
          <link rel='icon' href='/favicon.ico' />
        </Head>
        <Loader />
      </Fragment>
    );
  } else {
    return (
      <Fragment>
        <Head>
          <title>Dhaval Vira Resume</title>
          <meta
            name='description'
            content='online resume website of Dhaval Vira, cv of Dhaval Vira, portfolio of Dhaval Vira'
          />
          <link rel='icon' href='/favicon.ico' />
        </Head>

        <Component {...pageProps} />

        {/* react-hot-toast */}
        <Toaster position='top-right' reverseOrder={false} />
      </Fragment>
    );
  }
}

export default MyApp;
slhcrj9b

slhcrj9b1#

_app.jsx中,由于加载逻辑的原因,在4s后强制客户端呈现页面内容。这意味着当页面在服务器上预呈现时,您只能在服务器发送的HTML中获得Loader组件。
请完全移除载入逻辑,让您的网页可以在服务器端正确呈现。

function MyApp({ Component, pageProps }) {
    return (
        <Fragment>
            <Head>
                <title>Dhaval Vira Resume</title>
                <meta
                    name='description'
                    content='online resume website of Dhaval Vira, cv of Dhaval Vira, portfolio of Dhaval Vira'
                />
                <link rel='icon' href='/favicon.ico' />
            </Head>
            <Component {...pageProps} />
            {/* react-hot-toast */}
            <Toaster position='top-right' reverseOrder={false} />
        </Fragment>
    );
}

相关问题