You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js元标签开发环境正常生产环境失效问题及解决

生产环境下Next.js页面OG/Twitter元标签无法被Facebook/Twitter工具识别的解决方法

问题概述

我负责的项目包含静态和动态两种页面,开发环境下链接预览功能完全正常,已经通过本地的Open Graph检测工具、Twitter及Facebook分享调试工具验证过。但部署到生产环境后,Facebook调试工具和Twitter卡片验证工具无法正确识别页面的元标签。

代码示例

静态页NextSeo实现

<>
      <NextSeo
        title="FAQ - OpenLinks - Just Another Link in Bio tool"
        description="Get your answers for some common and most asked questions at OpenLinks."
        additionalMetaTags={[
          {
            name: "keywords",
            content:
              "OpenLinks faq,OpenLinks questions,OpenLinks common questions",
          },
          {
            name: "author",
            content: "Jayant Navrange",
          },
        ]}
        openGraph={{
          url: "https://openlinks.vercel.app/faq",
          title: "FAQ - OpenLinks",
          type: "website",
          description:
            "Get your answers for some common and most asked questions at OpenLinks.",
          images: [
            {
              url: "https://openlinks.vercel.app/favicon-310.png",
              width: 200,
              height: 200,
              alt: "Website Logo",
            },
          ],
          siteName: "OpenLinks",
        }}
        twitter={{
          cardType: "summary",
        }}
      />
</>

动态页NextSeo实现

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import Image from "next/image";
import styles from "../styles/Profile.module.css";
import { getIcon } from "../helpers/util";
import { isValid } from "../helpers/isValid";
import { NextSeo } from "next-seo";
import { JSDOM } from "jsdom";
import DOMPurify from "dompurify";
import Link from "next/link";
import {
  EmailShareButton,
  FacebookShareButton,
  LinkedinShareButton,
  RedditShareButton,
  TelegramShareButton,
  TwitterShareButton,
  WhatsappShareButton,
} from "react-share";
import {
  EmailIcon,
  FacebookIcon,
  LinkedinIcon,
  RedditIcon,
  TelegramIcon,
  TwitterIcon,
  WhatsappIcon,
} from "react-share";
import toast, { Toaster } from "react-hot-toast";
import { Spotify } from "react-spotify-embed";
const youtubeEmbed = require("youtube-embed");
let cnt = 0;

const shareOnSM = (urlToShare) => {
  toast(
    (t) => (
      <div>
        <h5>Share on</h5>
        <hr />
        <EmailShareButton url={urlToShare}>
          <EmailIcon size={25} round />
        </EmailShareButton>
        &nbsp;
        <LinkedinShareButton url={urlToShare}>
          <LinkedinIcon size={25} round />
        </LinkedinShareButton>
        &nbsp;
        <TwitterShareButton url={urlToShare}>
          <TwitterIcon size={25} round />
        </TwitterShareButton>
        &nbsp;
        <FacebookShareButton url={urlToShare}>
          <FacebookIcon size={25} round />
        </FacebookShareButton>
        &nbsp;
        <RedditShareButton url={urlToShare}>
          <RedditIcon size={25} round />
        </RedditShareButton>
        &nbsp;
        <WhatsappShareButton url={urlToShare}>
          <WhatsappIcon size={25} round />
        </WhatsappShareButton>
        &nbsp;
        <TelegramShareButton url={urlToShare}>
          <TelegramIcon size={25} round />
        </TelegramShareButton>
        <hr />
        <div className="float-end">
          <button
            type="button"
            className="btn btn-outline-primary"
            onClick={() => toast.dismiss(t.id)}
          >
            Cancel
          </button>
        </div>
      </div>
    ),
    {
      position: "bottom-right",
    }
  );
};

export default function SingleData({
  id,
  idAwake,
  last_login,
  dname,
  fname,
  dp,
  location,
  summary,
  url,
  pronoun,
  type,
  wdata,
  dpayd,
  bpayd,
  miscdata,
}) {
  const convertTime = () => {
    let d = new Date(last_login);
    return d.toLocaleTimeString();
  };

  const createMarkup = (cl) => {
    return { __html: cl };
  };

  return (
    <>
      <NextSeo
        title={
          dname === id
            ? `${dname} at OpenLinks`
            : `${id} not found at OpenLinks`
        }
        description={`${
          dname === id
            ? `This is the profile of ` +
              dname +
              ` find every link by this author at OpenLinks`
            : dname + " The profile of this user not exists at OpenLinks"
        }`}
        additionalMetaTags={[
          {
            name: "keywords",
            content: `${dname} profile, ${dname} openlinks`,
          },
          {
            name: "author",
            content: "Jayant Navrange",
          },
          {
            name: "twitter:title",
            content:
              dname === id
                ? `${dname} at OpenLinks`
                : `${id} not found at OpenLinks`,
          },
          {
            name: "twitter:description",
            content: `${
              dname === id
                ? `This is the profile of ` +
                  dname +
                  ` find every link by this author at OpenLinks`
                : dname + " The profile of this user not exists at OpenLinks"
            }`,
          },
          {
            name: "twitter:image",
            content: dp,
          },
        ]}
        openGraph={{
          url: `https://openlinks.vercel.app/${dname}`,
          title: `${dname === id ? dname : `${id} not found`} at OpenLinks`,
          type: "website",
          description: `${
            dname === id
              ? `This is the profile of ` +
                dname +
                ` find every link by this author at OpenLinks`
              : dname + " The profile of this user not exists at OpenLinks"
          }`,
          images: [
            {
              url: dp,
              width: 300,
              height: 157,
              alt: `Image of user ${dname}`,
            },
            {
              url: dp,
              width: 800,
              height: 600,
              alt: `Image of user ${dname}`,
            },
            {
              url: dp,
              width: 900,
              height: 800,
              alt: `Image of user ${dname}`,
            },
            {
              url: dp,
              width: 200,
              height: 200,
              alt: `Image of user ${dname}`,
            },
            { url: dp },
          ],
          siteName: "OpenLinks",
        }}
        twitter={{
          cardType: "summary",
        }}
      />
      --Other contents--
    </>
  );
}

export async function getServerSideProps(context) {
  const { params } = context;
  const { id } = params;

  const response = await fetch(
    `${process.env.NEXT_PUBLIC_FIREBASE_DATABASEURL}/users/${id}/.json`
  );
  const data = await response.json();
  const window = new JSDOM("").window;
  const purify = DOMPurify(window);
  const summary = purify.sanitize(data && data.summary);
  const dname = data && data.dname;
  const fname = data && data.fname;
  const pronoun = data && data.pronoun;
  const location = data && data.location;
  const type = data && data.type;
  const url = data && data.url;
  const last_login = data && data.last_login;
  const dp = data && data.dp;
  const idAwake = data && data.emailVer;

  const web = await fetch(
    `${process.env.NEXT_PUBLIC_FIREBASE_DATABASEURL}/users/${id}/websites.json`
  );
  const wdata = await web.json();
  const dpay = await fetch(
    `${process.env.NEXT_PUBLIC_FIREBASE_DATABASEURL}/users/${id}/digitalPay.json`
  );
  const dpayd = await dpay.json();
  const bpay = await fetch(
    `${process.env.NEXT_PUBLIC_FIREBASE_DATABASEURL}/users/${id}/bankPay.json`
  );
  const bpayd = await bpay.json();

  const misc = await fetch(
    `${process.env.NEXT_PUBLIC_FIREBASE_DATABASEURL}/users/${id}/miscData.json`
  );
  const miscdata = await misc.json();
  return {
    props: {
      id,
      idAwake,
      fname,
      dname,
      dp,
      location,
      type,
      url,
      pronoun,
      summary,
      last_login,
      wdata,
      dpayd,
      bpayd,
      miscdata,
    },
  };
}

解决方案

经过排查处理,以下部署配置可解决该问题:

  • Vercel平台:适配页面使用的getStaticProps或getServerSideProps渲染方式即可,无需额外配置。
  • Netlify平台:需遵循官方部署指南,并开启预渲染功能,确保元标签在页面首次加载时就已生成。

内容的提问来源于stack exchange,提问作者Jayant Navrange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:17:02