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

Next.js 13 appDir客户端路由下Embedded Tweet无法显示的解决方法

Next.js客户端路由下Twitter嵌入式推文加载问题的解决方案

问题根源

Next.js的客户端路由(通过Link组件跳转)不会重新执行全局脚本,Twitter的嵌入脚本仅在初始服务端渲染时扫描页面并生成iframe;路由跳转后新增的嵌入代码未被脚本识别,导致无法加载。

解决方法

1. 页面挂载时手动触发Twitter脚本初始化

利用React的useEffect钩子,在组件挂载(包括客户端路由跳转后的页面挂载)时,调用Twitter提供的twttr.widgets.load()方法重新扫描页面,初始化所有未加载的嵌入内容。若twttr对象未加载,则动态引入脚本:

import { useEffect } from 'react';

const TwitterEmbedInitializer = () => {
  useEffect(() => {
    const initWidgets = () => {
      if (window.twttr?.widgets) {
        window.twttr.widgets.load();
      } else {
        const script = document.createElement('script');
        script.src = 'https://platform.twitter.com/widgets.js';
        script.async = true;
        script.onload = () => window.twttr.widgets.load();
        document.body.appendChild(script);
      }
    };

    initWidgets();
  }, []);

  return null;
};

// 在需要嵌入推文的页面或根布局(layout.tsx)中引入该组件
export default TwitterEmbedInitializer;

2. 监听路由跳转事件全局处理

在_app.tsx(或App Router下的layout.tsx)中监听Next.js的routeChangeComplete事件,每次路由跳转完成后自动触发初始化,确保所有页面跳转后都能正常加载推文:

import { useEffect } from 'react';
import { useRouter } from 'next/router';

export default function MyApp({ Component, pageProps }) {
  const router = useRouter();

  useEffect(() => {
    const handleRouteComplete = () => {
      window.twttr?.widgets.load();
    };

    // 绑定路由事件
    router.events.on('routeChangeComplete', handleRouteComplete);

    // 初始化加载Twitter脚本
    const script = document.createElement('script');
    script.src = 'https://platform.twitter.com/widgets.js';
    script.async = true;
    document.body.appendChild(script);

    // 卸载时移除事件监听
    return () => router.events.off('routeChangeComplete', handleRouteComplete);
  }, [router]);

  return <Component {...pageProps} />;
}

3. 封装自定义Twitter嵌入组件

将推文嵌入逻辑封装为独立组件,通过twttr.widgets.createTweet()方法直接生成嵌入内容,避免依赖页面初始扫描:

import { useEffect, useRef } from 'react';

const TwitterTweet = ({ tweetId }) => {
  const containerRef = useRef(null);

  useEffect(() => {
    if (!containerRef.current) return;

    const loadTweet = async () => {
      // 确保脚本已加载
      if (!window.twttr) {
        await new Promise(resolve => {
          const script = document.createElement('script');
          script.src = 'https://platform.twitter.com/widgets.js';
          script.async = true;
          script.onload = resolve;
          document.body.appendChild(script);
        });
      }
      // 生成推文嵌入
      window.twttr.widgets.createTweet(tweetId, containerRef.current);
    };

    loadTweet();
  }, [tweetId]);

  return <div ref={containerRef} />;
};

// 使用示例:<TwitterTweet tweetId="1456789012345678901" />
export default TwitterTweet;

关键说明

预加载Twitter脚本无法解决问题,因为脚本仅在初始页面加载完成后自动扫描一次DOM;客户端路由跳转后新增的DOM内容不会被自动识别,必须通过twttr.widgets.load()或createTweet()方法手动触发初始化。

内容的提问来源于stack exchange,提问作者Yoann Buzenet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 00:53:13