はじめに
当ブログの記事は、mdファイルをHTMLにパースして表示しており、ブログサービスによくある「ブログカード」や「カードリンク」的な機能がありません。
実装するには、はてなブログさんが提供しているパーツをそのまま利用する手もあるようですが、リンク内がiframeになってしまい扱いが若干面倒でした。
ですので、せっかくですし簡単な方法で実装してみました。
カードのパターンと見た目
youtubeやx(twitter)の埋め込みは一旦おいておき、今回用意したのは下記のシンプルな2パターンです。
- 一般的なwebサイトへのリンク
- Amazonの商品リンク(アフェリエイトなし)
一般的なリンクの例
Zenn|エンジニアのための情報共有コミュニティ
zenn.dev
note ――つくる、つながる、とどける。
note.com
Amazonの商品リンクの例
実装方法
考え方とロジック
方法としては、マークダウン記法のコードブロックを利用します。
コードのシンタックスハイライトに用いられる「言語識別子」をデータとして受け取り、独自の識別子である「Link」もしくは「Amazon」である場合、分岐してコンポーネントを出し分けます。
この方法は下記の記事が大変参考になりました。ありがとうございました。
(25/01/30追記)下記リンクは削除されているようです
NEXTJSのマークダウンブログにAMAZONやYOUTUBEのEmbedを表示する
https://onofblog.com/post/2024-03-31-markdownembed
また、独自の識別子の場合、ブロックの中は以下のとおりです。
- タイトル
- ホスト
- URL
- 画像
```Link ← 独自の識別子
Zenn|エンジニアのための情報共有コミュニティ ← タイトル
zenn.dev ← ホスト
https://zenn.dev ← URL
https://static.zenn.studio/images/logo-only-dark.png ← 画像
```
```javascript ← 一般的な言語識別子
var foo = function (bar) {
return bar++;
};
console.log(foo(5));
```
なおreact-markdownだけではシンタックスハイライト対応が不十分なので、react-syntax-highlighterを導入しました。
下記の記事が大変参考になりました。ありがとうございました。
react-markdownとreact-syntax-highlighterを利用して、コードブロックをカスタマイズする
www.newt.so
コードの概要
細かな部分を省略していますが、全体のコードは以下のようになります。
switch文を使って独自の識別子の判定し、コンポーネントを出し分けます。今後youtubeやx(twitter)の埋め込みを実装する場合にも対応できます。
1export default ({ 2 children 3} => { 4 const match = ... // コードブロックの識別子を取得 5 6 const embedType = ... // 独自の識別子を取得 7 if (embedType) { // 独自の識別子の場合 8 const { 9 title, 10 host, 11 url, 12 image 13 } = getData(children); // データを取得 14 15 switch (embedType) { // 分岐 16 case 'Link': 17 return ( 18 <Link> 19 ... 20 </Link> 21 ); 22 case 'Amazon': 23 return ( 24 <Link> 25 ... 26 </Link> 27 ); 28 } 29 } 30 return match ? ( // 一般的な識別子の場合 31 <SyntaxHighlighter> // シンタックスハイライト 32 {children} 33 </SyntaxHighlighter> 34 ) : ( 35 <code> // プレーンなcodeブロック 36 {children} 37 </code> 38 ); 39};
すべてのコードを確認したい場合は、手前味噌ですがこちらの私のgithubをご参照ください。
まとめ
とても良い勉強になりました。
カードリンクのデータは、実は自作の適当なスニペットを対象サイトで実行して取得しています。
このあたりもサーバーサイドで実装できれば、もっと便利になるかもしれません。
ではまた。