Next.jsでYouTube埋め込みを作成する
Next.jsでブログ兼ポートフォリオサイト的なものを作成しました(チュートリアルを少しいじったもの)。
その際に、markdownファイルにYouTubeの埋め込みができるようにしたので書き残しておきます。
完成系
コードブロックの言語名にYouTubeと指定して、動画のIDを入れます。
以下のように表示されます。
やっていること
ReactMarkdown
でmarkdownをHTMLに変換する際、code
の箇所を独自にカスタマイズします。
言語名の部分がYouTubeだったら、react-youtube
というライブラリのコンポーネントに変換する、という処理を行っています。
変換処理部分
<ReactMarkdown remarkPlugins={[remarkGfm]} components={{ code: Code }}>
{post.content}
</ReactMarkdown>
ここでReactMarkdown
コンポーネントに{{ code : Code }}
を指定することで、code
タグの処理をCode
コンポーネントにゆだねることができます。
const Code: CodeComponent = ({ inline, className, children, ...props }) => {
const match = /language-(\w+)/.exec(className || '');
const matchFileName = className && className.includes(':') ? className.split(':') : null;
if (match && match.length > 0 && match[1] === 'youtube') {
return (
<div className='youtube-wrap'>
<YouTube videoId={children[0] as string} />
</div>
);
}
正規表現で言語名部分を取得し、youtube
と書かれていたら、react-youtube
からインポートしたYouTube
コンポーネントに動画のIDを渡します。
そのままだと横幅が指定されており、スマホだと横スクロールできてしまうので、youtube-wrap
クラスをつけてはみ出ないようにします。
.youtube-wrap iframe {
margin: 1rem 0;
aspect-ratio: 16 / 9;
width: 100%;
max-width: 680px;
height: auto;
}
youtube-wrap iframe
クラスにはaspect-ratio
を指定して比率がいい感じになるようにしています。
一応ソースコードのリンクは貼りましたが、全体的に見たい方はこちらのリポジトリを見て見てください。
感想
リンクを貼っただけで自動的に埋め込みにするのはunified
などの解析の技術が必要で、そこまで到達するのはすごく大変そうだったので逃げてしまいました。
いつか勉強してみたいです。
が、普通に実用的なものが作れたので満足しています。
多くのサービスがただリンクを貼りつけただけで埋め込みにしてくれますが、改めてすごいことやってるんじゃないかって思いました。
Discussion