なんとシンプルなデザイン
はじめに
細々と運用していたポートフォリオサイトにCMSを統合した。お仕事でSveltekitとヘッドレスCMSを利用したWebサイトを構築するので、その習作も兼ねている(実際は、お仕事でこのあたりを味見したら、個人開発でやってみよう!という気持ちになったため)。
ヘッドレスCMSの選択肢
お仕事ではmicroCMSを利用しているため、個人開発ではNewtを使ってみた。
microCMSとの比較
- 無料枠はNewtの方が遊べる
- UIのクオリティはNewtの方が優れている
- エディタはmicroCMSの方が好き(画像がドラッグドロップ出来ないのはめんどう)
- 開発体験はどちらも同等。SDKのTypeScriptの型定義が、Newtの方が使いやすいかも
- NewtにはCDNモードがあって、これがmicroCMSよりも速い、ならうれしいかも
SveltekitとCloudflare Pages
せっかくなので完全にサーバーサイドレンダリング(SSR)とする。静的生成(SSG)はインフラは安く済むけどそのためのコードを書くのはめんどくさいし、せっかくエッジでサーバー動かせるので。Sveltekitはもう本当に素晴らしくて、Next.jsで理解が難しかったSSR周りが、Svelteらしく実装されていて直感的に利用できる。ランタイムも簡単に変えられる(adapterを差し替えればよい。実際、お仕事ではAWS Lambdaで動かしていたりする。現状でコードに違いもない)。
Cloudflare Pagesは、特に強い気持ちで選んではいなくて、今までCloudflare Pagesで動かしてたし、ドメインもCloudflareにあるし…ということで、変更はしなかった。今から新たに作るならAWS Lambdaで動かすと思う(Lambda向けアダプターを使うという意味ではなく。これは今後記事にする機会があれば、する)。エッジゆえの制限がきついことがたまにあるので。
埋め込みが正常に動かない話
CMSからは生HTMLの文字列が得られるのだが、Sveltekitでは以下のように実装できる。
// data.post.bodyにHTML文字列が入っているとして
<!-- eslint-disable svelte/no-at-html-tags -->
{@html data.post.body}
なおHTML文字列は全くサニタイズされないので、信頼できるソースの文字列のみを利用しよう。
https://svelte.dev/docs/special-tags#html
Newtは埋め込み機能をiframelyで実現していて、iframelyはクエリパラメータで渡されたURLを見に行って画像を生成するようなアプローチをとっていそう。これが非同期っぽく動くのだけど、その書き換えに失敗したり、しなかったりする(成功率10%くらい)。
失敗
成功
非同期で画像を設置するタイミングとSveltekit側のレンダリングのタイミングがなんかアレなのかとか、雑に推測している。現状はこのまま放っておく…。
追記
以下の記事を参考に、解決。
正直、SveltekitがどのようにHTMLを「レンダリング」しているのかとかは全くわからない、俺たちは雰囲気でフロントエンドをやっている。とにかく、上記の記事をSveltekitに読み替えて、下記のように実装すると解決した。
import { onMount } from 'svelte';
onMount(() => {
const script = document.createElement('script');
script.src = '//cdn.iframe.ly/embed.js';
document.body.appendChild(script);
});
おわりに
- Sveltekitはすばらしい
- CMSはどれを使っても大概のことはできるでしょう