在Next.js+Nextra项目的MDX文件中嵌入YouTube视频报错求助
在Nextra博客的MDX中嵌入YouTube视频时编译报错的解决方法
问题背景
使用Portfolio Starter Kit搭建旅行博客,尝试在MDX文章中嵌入可原地播放的YouTube视频,按以下步骤操作后执行yarn run build出现编译错误:
- 安装
react-youtube包:yarn add react-youtube - 创建
components/YouTube.js自定义组件 - 在
next.config.js的withMDX配置中注册youtube组件 - 在MDX中使用
<youtube videoId="dQw4w9WgXcQ" />
报错信息:
Failed to compile. ./pages/ajaveeb/2023-02-18-youtube-embedding.mdx TypeError [ERR_INVALID_ARG_TYPE]: The "from" argument must be of type string. Received undefined at new NodeError (node:internal/errors:400:5) at validateString (node:internal/validators:163:11) at Object.relative (node:path:1191:5) at loader (file:///Users/kristjan.roosild/repos/what-does-this-button-do/node_modules/nextra/dist/loader.mjs:85:42)
错误原因
Portfolio Starter Kit基于Nextra构建,Nextra的MDX自定义组件注册逻辑与原生@next/mdx不同。直接在withMDX的options里配置components会导致Nextra的loader无法正确解析组件路径,从而抛出参数类型错误。
解决步骤
1. 保留已创建的YouTube组件
确保components/YouTube.js代码不变:
import YouTube from 'react-youtube'; const YouTubeComponent = ({ videoId }) => { const opts = { height: '360', width: '640', playerVars: { autoplay: 0, }, }; return <YouTube videoId={videoId} opts={opts} />; }; export default YouTubeComponent;
2. 修改Nextra配置文件
打开next.config.js,将原有的withMDX配置替换为Nextra标准配置,通过mdxOptions注册自定义组件:
const withNextra = require('nextra')({ theme: 'nextra-theme-blog', themeConfig: './theme.config.js', // 注册MDX自定义组件 mdxOptions: { components: { youtube: require.resolve('./components/YouTube.js') } } }) module.exports = withNextra()
注意:若项目原本已有
withMDX配置,需合并到Nextra的mdxOptions中,不可单独使用withMDX。
3. 备选方案:通过布局组件传递自定义组件
若上述方法不生效,可在博客根布局组件中使用MDXProvider传递组件:
- 安装依赖(未安装时执行):
yarn add @mdx-js/react - 修改
pages/_layout.js(或_layout.tsx):
import { MDXProvider } from '@mdx-js/react' import YouTubeComponent from '../components/YouTube' const components = { youtube: YouTubeComponent } export default function BlogLayout({ children }) { return ( <MDXProvider components={components}> {children} </MDXProvider> ) }
4. 重新测试
在MDX中继续使用<youtube videoId="dQw4w9WgXcQ" />,执行yarn run build验证报错是否解决。
内容的提问来源于stack exchange,提问作者kristjanroosild
相关产品推荐
相关产品推荐

