---
title: "新しい個人ウェブサイト"
date: "2026-01-04"
tags: ["Cache-Control","FOUC","Sanity CMS","Flipnote Studio"]
---

# 新しい個人ウェブサイト

## 概要

個人ウェブサイト兼ブログを作りました。色々技術的な部分とかビジュアルスタイルについて書きます。

## 技術的詳細

#### Sanity CMSでのコンテンツ管理

3つのドメインで異なる役割を持たせています：

- **kynantokoro.com**: 公開済みコンテンツのみを表示
- **draft.kynantokoro.com**: 下書きを含む全てのコンテンツを表示（Sanity CDNを無効化し、ほぼ即時でプレビュー可能にしています）
- **cms.kynantokoro.com**: Sanity Studio（コンテンツ編集画面）

draft版とcms版はCloudflare Accessでアクセス管理を行っています。

#### FOUCのないテーマ切り替え

ダークモード/ライトモードの切り替えでよくある問題が、FOUC（Flash of Unstyled Content）です。Cookieを使ってSSRでテーマを適用する方法もありますが、ブログのようにユーザーによらず同じコンテンツを提供するサイトでは、HTTP Cache-Controlとの相性が悪くなります。

一度Cookieベースのアプローチを試した上で、最終的にはクライアントサイドでのテーマ切り替えを採用しました。`<head>`タグ内でCSSの描画が始まる前に、同期的にテーマのattributeやclassをセットすることで、FOUCを完全に防ぎながら、HTMLレスポンスは全て同じ内容になり、HTTP Cache-Controlヘッダーを使った積極的なキャッシングが可能になります。

#### AI翻訳機能

CMS内に独自のAI翻訳機能を実装しました。日本語で記事を書いた後、ワンクリックで英語に翻訳できます(逆も然り)。翻訳エンジンにはClaude（Anthropic）を使用しています。

記事はSanityのPortable Text形式（JSONベースの構造化されたリッチテキスト）で管理されており、埋め込み画像、カスタムブロック（ゲーム埋め込み、オーディオプレイヤーなど）、テキストのスタイリング、文書構造などを保ったまま翻訳できます。

## ビジュアルスタイル

サイトのビジュアル面では、ニンテンドーDSの「うごくメモ帳（うごメモ）」で作成したアニメーションを活用しています。

#### トップページのGIF

プロフィール画像には、DSの画面いっぱいに描いた10フレームほどのアニメーションをGIF化したものを使用しています。SSRやHTTP Cacheの挙動を視覚的に確認できるよう、サーバー側で彩度をランダムに生成しています。ページをリロードすると色味が変わるのは、実はキャッシュの動作確認のためでもあります。

#### ブログエントリーのキーイメージ

各ブログエントリーには、seed値に基づいて決定的に生成されるキーイメージが表示されます。以下のパラメータがseedから決まります：

- GIFのフレームindex（どのフレームを使うか）
- Zoom倍率
- 傾き
- 色相（hue）

実際に画像を生成しているわけではなく、CSSのプロパティを変更しているだけです。軽量かつ柔軟にビジュアルバリエーションを生み出せます。

完全にランダムだと面白くないので、「志向性」を持たせています。例えば、傾きは基本的に90度単位で、たまに斜めの角度が出るようにしています。このような制約により、ランダムでありながら統一感のあるビジュアルになっています。
