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
相关产品推荐
相关产品推荐

