Misskeyの埋め込みをHugoで利用する
Table of Contents
Misskeyのv2024.9.0リリースから待望の埋め込み機能が使えるようになっていたので、HugoのShortcodeから利用できるようにしてみる
概要

ウェブサイトへの埋め込み | Misskey Hub
Misskeyで新しく追加されたウェブサイトへのノート埋め込み機能を、Hugoで利用するための方法を考える。
埋め込みのやり方は以下のコードスニペットを挿入するだけ。
<iframe
src="https://<HOST>/embed/notes/<NOTE_ID>"
data-misskey-embed-id="v1_<RANDOM>"
loading="lazy"
referrerpolicy="strict-origin-when-cross-origin"
style="border: none; width: 100%; max-width: 500px; height: 300px; color-scheme: light dark;"
></iframe>
<script defer src="https://<HOST>/embed.js"></script>
ここで、プレースホルダに入れる値はそれぞれ以下の通り。
- HOST: Misskeyのホスト名。自分の場合は
misskey.4nm1tsu.com
- NOTE_ID: 該当のノートのID
- RANDOM: embed.jsで利用するための、同一ページ内で一意なランダム文字列。
misskeyのwebクライアントから特定のノートを指定することで上記埋め込みコードを生成することもできるが、 どちらかというと事前にshortcodeを作成しておいて、
{{< misskey <NOTE_ID> <UUID> >}}
みたいな感じで利用したい。
UUIDを自動生成することも考えたが、
- seed値として記事の内容をもとに生成→そもそも同一ページ内のUUIDが一致してしまう
- seed値として時刻をもとに生成→記事のビルド毎に違うUUIDが生成されてしまう(コンテンツに変更を加えていないのにUUIDが変わるのは気持ち悪い)
上記の理由から、以下のキーマップを設定して、UUIDは都度挿入することにした。
参考:(neo)vimでUUIDを生成・挿入するkeymap
nnoremap <leader>uu i<c-r>=trim(system('uuidgen'))<cr><esc>
記事の内容+カウンタ変数を使ってUUIDを自動生成する実装も考えたが、面倒臭くてやめた。
ノートの埋め込み
コード
layouts/shortcodes/misskey.html
{{ $note_id := .Get 0 }}
{{ $uuid := .Get 1 }}
{{ $host := "misskey.4nm1tsu.com" }}
<iframe
class="misskey-note"
src="https://{{ $host }}/embed/notes/{{ $note_id }}"
data-misskey-embed-id="v1_{{ $uuid }}"
loading="lazy"
referrerpolicy="strict-origin-when-cross-origin"
style="border: none; width: 100%; max-width: 500px; height: 300px; color-scheme: light dark;"
></iframe>
<script defer src="https://{{ $host }}/embed.js"></script>
assets/sass/misskey.scss
.misskey-note {
display: block; /* ブロック要素にすることでmarginを適用 */
margin: 0 auto 1rem; /* 上下のマージンを指定しつつ中央揃え */
}
(おまけ)タイムラインの埋め込み
タイムラインも同様にして埋め込めるらしいので、Aboutページに以下を入れてみることにした。
Misskey Hubでの説明にある通り、user_idは@から始まるユーザ名とは違うので、「コントロールパネル」→「ユーザー」のRawデータなどから持ってくると良いと思う。
記事中で使うことはないと思うので、こちらに関してはshortcodeは作らない。
コード
index.html
<div class="container index">
<div class="about-me">
<img src="https://avatars.githubusercontent.com/u/40907120?v=4">
<p class="name">4nm1tsu</p>
<div class="icon-container">
<a href="https://github.com/4nm1tsu/" target="_blank" rel="noopener noreferrer">
<ion-icon size="large" name="logo-github" class="icon-highlight"></ion-icon>
</a>
<a href="https://misskey.4nm1tsu.com/@4nm1tsu" target="_blank" rel="noopener noreferrer">
<ion-icon size="large" name="logo-mastodon" class="icon-highlight"></ion-icon>
</a>
<a href="mailto:4nm1tsu@4nm1tsu.com">
<ion-icon size="large" name="mail-outline" class="icon-highlight"></ion-icon>
</a>
</div>
</div>
<iframe
src="https://misskey.4nm1tsu.com/embed/user-timeline/9gozgz6f35?maxHeight=450"
data-misskey-embed-id="v1_951fc0f5-9805-49c2-bea3-9ea1b4c471b8"
loading="lazy"
referrerpolicy="strict-origin-when-cross-origin"
class="timeline"
>
</iframe>
</div>
assets/sass/index.scss
...
.about-me img {
margin-left: auto;
margin-right: auto;
border-radius: 50%;
}
p.name {
text-align: center;
font-size: 2rem;
}
.about-me .icon-container {
text-align: center;
a {
text-decoration: none;
}
}
.container .index {
display: flex;
justify-content: center;
align-items: stretch; /* 横並びのとき高さを揃える */
gap: 20px;
flex-direction: row; /* 横並びに設定 */
height: 100%; /* 親要素の高さを100%に */
}
.about-me {
display: flex;
flex-direction: column; /* 内容を縦に並べる */
justify-content: center; /* コンテンツを中央揃え */
width: auto;
max-width: 240px; /* 最大幅を設定 */
padding: 20px; /* パディングを追加 */
box-sizing: border-box; /* パディングを含むボックスモデル */
height: 450px;
}
.timeline {
border: none;
height: 450px;
width: 100%;
max-width: 500px;
overflow: auto;
color-scheme: light dark;
flex: 1; /* 高さを親要素に合わせるためにフレックスプロパティを使用 */
}
/* Responsive adjustments */
@media (max-width: 900px) {
.container .index {
flex-direction: column; /* 900px以下で縦並びに変更 */
align-items: center; /* 縦並びのとき中央寄せ */
height: auto; /* 縦並び時は自動高さ */
}
.about-me, .timeline {
width: 100%; /* 各要素を幅100%に */
max-width: 500px; /* 最大幅を設定 */
text-align: center; /* 中央揃えに */
}
.timeline {
max-height: none;
flex: none;
}
}
おわりに
一度作ってしまえば、あとはmisskeyからnote_idだけコピペすればスタイルは適用されるので、 Hugoでノート埋め込み機能を利用する場合はShortcodeを使ったほうが絶対楽だと思う。
参考記事

Insert UUIDs in Vim / Neovim – Grailbox

Creating a unique id for repeated custom shortcode
Read other posts