Next.js重新加载脚本标记

ulydmbyx  于 2023-02-08  发布在  其他
关注(0)|答案(1)|浏览(176)

我试图嵌入第三方评论脚本到我的next.js例如. (disqus,remark 42,hyvor) 但不幸的是它只在第一次加载时加载并且我必须再次重新加载页面以显示嵌入的第三方脚本,但它与react/next.js的模式相反,因为当您通过Link组件导航到另一个页面时,next.js不会重新加载,因此,我正在寻找一个解决方案,只重新加载脚本组件本身,使我的评论小部件出现在网站的每一篇文章的页面。

代码:

export const getStaticPaths: GetStaticPaths = async () => {
  const data = await getArticles();

  const paths = data.map((article) => ({
    params: {
      slug: article?.slug,
    },
  }));

  return {
    paths,
    fallback: true,
  };
};

export const getStaticProps = async ({
  params,
}: GetStaticPropsContext<{ slug: string }>) => {
  const article = await getArticleByProp("slug", params!.slug);

  return {
    props: {
      article: article[0],
    },
    notFound: article.length === 0,
    revalidate: 60,
  };
};

const ArticlePage = ({
  article,
}: InferGetStaticPropsType<typeof getStaticProps>) => {
  const router = useRouter();
  const articleDate = useFormattedDate(
    article?.createdAt ? new Date(article.createdAt) : new Date(),
    "distance"
  );

  if (router.isFallback) {
    return <div>Loading...</div>;
  }

  return (
    <Container>
      <SEOHeader
        title={article?.title}
        author={article?.author}
        description={article?.excerpt}
        ogImage={article?.featuredImage}
        canonical={article?.slug}
      />
      <Wrapper>
        <ArticleWrapper>
          <ArticleHeader>
            <small className="category">{article?.category}</small>
            <h1 className="title">{article?.title}</h1>
            <p className="contributor">
              <span>
                By <strong> {article?.author}</strong> <br />
              </span>
            </p>
            <div className="date">
              <Clock size={18} />{" "}
              <span>{article?.createdAt ? articleDate : "N/A"}</span>
            </div>
            <button className="share">
              <Share size={24} />
            </button>
          </ArticleHeader>
          <ArticleBody>
            {!!article?.featuredImage && (
              <Featured>
                <Image
                  src={article.featuredImage}
                  layout="responsive"
                  width={1920}
                  height={1080}
                  alt="Featured article image"
                />
              </Featured>
            )}
            <ArticleExcerpt>{article?.excerpt}</ArticleExcerpt>
            <ArticleMdx>{article?.body}</ArticleMdx>
          </ArticleBody>
          <div id="remark42">{""}</div>

          {/* <Script id="remark42-script" strategy="afterInteractive">
            {`
              var remark_config = {
                host: "http://localhost:5010",
                site_id: "mysite",
                show_email_subscription: false,
                url: "${process.env.BASE_URL + router.asPath}"
              }
              
              !(function (e, n) {
                for (var o = 0; o < e.length; o++) {
                  var r = n.createElement("script"),
                    c = ".js",
                    d = n.head || n.body;
                  "noModule" in r ? ((r.type = "module"), (c = ".mjs")) : (r.async = !0),
                    (r.defer = !0),
                    (r.src = remark_config.host + "/web/" + e[o] + c),
                    d.appendChild(r);
                }
              })(remark_config.components || ["embed"], document);
            `}
          </Script> */}

          {/* <div id="hyvor-talk-view"></div>
          <Script id="hyvor-script">
            {`
                  var HYVOR_TALK_WEBSITE = 7527;
                  var HYVOR_TALK_CONFIG = {
                      url: "${process.env.BASE_URL + router.asPath}",
                      id: "${article?.id}",
                  };
            `}
          </Script>
          <Script
            async
            src="//talk.hyvor.com/web-api/embed.js"
            strategy="lazyOnload"
            onLoad={() =>
              console.log(
                `script loaded correctly, window.FB has been populated`
              )
            }
          /> */}

          {/* <Discussion id={article?.id} title={article?.title} /> */}

          <Script id="remark42-test">{`
          const remark_config = {
            host: 'https://demo.remark42.com',
            site_id: 'remark',
          };
          window.remark_config = remark_config;
          !function(e,n){for(var o=0;o<e.length;o++){var r=n.createElement("script"),c=".js",d=n.head||n.body;"noModule"in r?(r.type="module",c=".mjs"):r.async=!0,r.defer=!0,r.src=remark_config.host+"/web/"+e[o]+c,d.appendChild(r)}}(remark_config.components||["embed"],document);
          `}</Script>
        </ArticleWrapper>
        <Recommended>
          <h2>Recommended</h2>
          <ArticleCard card={article} variant="slim" />
          <ArticleCard card={article} variant="slim" />
          <ArticleCard card={article} variant="slim" />
          <ArticleCard card={article} variant="slim" />
        </Recommended>
      </Wrapper>
    </Container>
  );
};

export default ArticlePage;
j7dteeu8

j7dteeu81#

也许这有助于解决类似的问题:
next/script提供了更新的onReady prop,它对于处理第三方Map、小部件等非常有用。
您可以在脚本首次加载时在脚本的load事件之后执行代码,然后使用onReady属性在每个后续组件重新装载之后执行代码。
文档中的代码示例:

<Script
        id="google-maps"
        src="https://maps.googleapis.com/maps/api/js"
        onReady={() => {
          new google.maps.Map(mapRef.current, {
            center: { lat: -34.397, lng: 150.644 },
            zoom: 8,
          })
        }}
      />

相关问题