Nuxt Contentで Markdown をつかって記事を管理する際に、記事内の外部リンクにアイコンをつけたい場合のやり方
外部リンクを別タブにする
まず、前提として外部リンクは別のタブにすることが多いですよね。
これ自体は、rehype-external-link
というパッケージを使えば簡単に設定できます。
export default defineNuxtConfig({
content: {
markdown: {
rehypePlugins: {
'rehype-external-links': {
target: '_blank',
rel: ['noopener', 'noreferrer']
}
}
}
}
})
こんな感じで、Markdown コンテンツをパースした際に自動で target="_blank"
と rel
に noopener
とnoreferrer
をつけるといったことが出来るようになります。
ところが、同じような感じにクラスをつけようと思っても、この設定の中に class
とか className
といったものは無く、外部リンクにクラスをつけるといったことは出来ないようです。
外部リンクにアイコンをつける
ではどうしたらよいかという話なのですが、class 関係のオプションはないんですが、外部リンクだというメッセージを出すための content
というものがありました。
いろんなところの記事を見るとここで type を element にして VUE の SFC のタグを入れたり、SVG タグを書いたりする方法で出来るっぽい感じだったのですが、どうにもエラーになってしまうようです。
(見た記事が古かったので今は出来ないのかも)
で、content
はなにができるのかというと、ここに何か書くと、外部リンクの a
要素の最後、タグを閉じる直前に span
が挿入されてその中に content に記入した文字列が注入される、というものでした。
また、この span
のプロパティ自体は、contentProperties
という別のキーで指定すれば良いみたいです。
ということで、こんな感じに書き足します。
export default defineNuxtConfig({
content: {
markdown: {
rehypePlugins: {
'rehype-external-links': {
target: '_blank',
rel: ['noopener', 'noreferrer'],
content: {
type: 'text',
value: 'open_in_new'
},
contentProperties: {
className: 'material-symbols external-link'
}
}
}
}
}
})
これで、外部リンクの後ろに
<span class="material-symbols external-link">open_in_new</span>
といった感じの span が挿入されるようになりますので、ここにスタイルをあてます。
.material-symbols {
font-family: 'Material Symbols Outlined', serif;
font-weight: 300;
font-style: normal;
font-size: 100%;
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
&.external-link {
margin: 0 0.25em;
}
}
別案
注入される span
自体を material-symbols 様にするのではなくて、あくまでその span についてる特定のクラスに対して material-symbols が展開されるようにする方法でもいいかもしれません。
export default defineNuxtConfig({
content: {
markdown: {
rehypePlugins: {
'rehype-external-links': {
target: '_blank',
rel: ['noopener', 'noreferrer'],
content: {
type: 'text',
value: ''
},
contentProperties: {
className: 'external-link'
}
}
}
}
}
})
このパターンの場合は、先ほどとは違って、:after
を使いますので span
自体は空っぽにしておきます。
value が空文字でも空の span が出ることを利用してます。
<span class="external-link"></span>
なので、これに対して after にアイコンが出るように設定します。
.external-link:after {
content: '\e89e';
margin: 0 0.25em;
font-family: 'Material Symbols Outlined', serif;
font-weight: 300;
font-style: normal;
font-size: 100%;
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
/* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */
text-rendering: optimizeLegibility;
}