<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Yumrith</title><description>Yuma Shintani</description><link>https://www.y-shin.net/</link><language>ja</language><item><title>Markdownノートエディタ「Notyra」をリリースしました</title><link>https://www.y-shin.net/posts/notyra/</link><guid isPermaLink="true">https://www.y-shin.net/posts/notyra/</guid><description>ローカル環境で動作するデスクトップ用の軽量Markdownノートエディタ「Notyra」をリリースしました。</description><pubDate>Sun, 05 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;先日、ローカル環境で動作するデスクトップ用の軽量Markdownノートエディタ「Notyra」をリリースしました。
&lt;a href=&quot;/work/&quot;&gt;Work&lt;/a&gt;でこれまで個人開発してきたプロダクトを紹介していますが、ブログで紹介するのは初めてです。&lt;/p&gt;
&lt;p&gt;完全無料(MIT)で公開していますので気軽に利用してみてください。&lt;/p&gt;
&lt;h2&gt;Notyraとは？&lt;/h2&gt;
&lt;p&gt;Notyraは、コンピュータのローカルに保存されたMarkdownファイルを管理できる軽量デスクトップノートエディタです。&lt;br /&gt;
クラウドに保存することなく完全オフライン環境でセキュアに利用することが出来ます。&lt;br /&gt;
また、アプリはオープンソースで公開していますので、完全無料でご利用いただけます。&lt;/p&gt;
&lt;p&gt;https://notyra.y-shin.net&lt;/p&gt;
&lt;p&gt;Windows・Mac・Linux向けに、以下のダウンロードページで提供しています。&lt;br /&gt;
お好みのプラットフォーム・形式をご利用ください。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!WARNING]
Notyraは現在アプリ署名がされていないため、セキュリティ警告が表示されることがあります。安全にアプリを起動する方法については、ダウンロードページをご確認ください。
アプリ署名についてはOSSであれば無償で発行できる機関があるようなので、今後検討していきたいと思います。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;https://notyra.y-shin.net/download&lt;/p&gt;
&lt;h2&gt;なぜNotyraを作ったのか&lt;/h2&gt;
&lt;p&gt;元々はメモフォルダを作り、Visual Studio Code上で作成したメモを保存していました。&lt;br /&gt;
しかし、Visual Studio Codeの起動が遅くパッとメモを取りたい時に少しストレスになっていました。&lt;br /&gt;
また、メモを取るのに特化したエディタでは無いのでメモの一覧が見づらいというのもありました。&lt;/p&gt;
&lt;p&gt;代替手段を探していたのですが、ほとんどがクラウド同期・単一のマークダウンファイル・ウェブアプリで完全ローカルで動作するデスクトップアプリで良いものが見つかりませんでした。&lt;br /&gt;
良いものが無いのであれば作ってみようと思ったのが開発のきっかけです。&lt;/p&gt;
&lt;h2&gt;Notyraの特徴&lt;/h2&gt;
&lt;h3&gt;完全ローカル環境で動作&lt;/h3&gt;
&lt;p&gt;Notyraは外部と接続せず完全ローカル環境で動作します。クラウドへの同期機能もNotyraには備わっていません。&lt;br /&gt;
ノートのバックアップが必要な場合はルートフォルダをご自身で契約頂いているOneDriveやGoogle Driveの同期対象に設定いただくことで自動バックアップが可能です。&lt;/p&gt;
&lt;h3&gt;リアルタイムプレビュー&lt;/h3&gt;
&lt;p&gt;Notyraは3種類のモードでビュアーを切り替えることが出来ます。&lt;br /&gt;
その中でもエディタとプレビューの分割表示に関しては入力した内容がプレビューにリアルタイムで表示されるようになっています。
また、スクロールもエディタとプレビューで同期するようになっています。&lt;br /&gt;
さらに、対象のノートをダブルクリックすることで別ウィンドウで表示・編集することが可能です。&lt;/p&gt;
&lt;h3&gt;PDF・HTMLエクスポート&lt;/h3&gt;
&lt;p&gt;ノートはPDF・HTML形式でエクスポートすることも可能です。&lt;/p&gt;
&lt;h3&gt;アプリテーマのカスタマイズ&lt;/h3&gt;
&lt;p&gt;この辺りは、おまけ機能のようなものですが、アプリの見た目を変えられる機能も提供しています。
ライトモード・ダークモードの切り替えはもちろんのこと、色合いも変更することが出来ます。&lt;br /&gt;
公式としていくつかのテーマを提供していますが、ご自身でテーマを作成して適用させることも出来ます。&lt;/p&gt;
&lt;h3&gt;パンくずリスト&lt;/h3&gt;
&lt;p&gt;Notyraのこだわりポイントですが、サイドバーのフォルダリストで対象の子フォルダや孫フォルダをダブルクリックすると、そのフォルダをトップに持ってくることが可能です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;folder-list-1.webp&quot; alt=&quot;folder-list-1&quot; /&gt; &lt;img src=&quot;folder-list-2.webp&quot; alt=&quot;folder-list-2&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Notyra UI&lt;/h2&gt;
&lt;p&gt;ルートフォルダ選択後は以下のような画面に遷移します。
&lt;img src=&quot;main-ui.webp&quot; alt=&quot;Main UI&quot; /&gt;&lt;/p&gt;
&lt;p&gt;左からサイドバー、ノートリスト、エディタと3つの主要なセクションで構成されています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;サイドバー : 左側のサイドバーは、フォルダツリーを表示し、ノートの階層的な管理を可能にします。&lt;/li&gt;
&lt;li&gt;ノートリスト : サイドバーの隣には、選択したフォルダ内のMarkdownノートのリストが表示され、簡単にアクセスできます。&lt;/li&gt;
&lt;li&gt;エディタ : 画面の右側には、選択したノートを編集するためのMarkdownエディタが配置されており、リアルタイムでプレビューも可能です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;新しいウィンドウでノートを開く&lt;/h3&gt;
&lt;p&gt;ノートリストで対象のノートをダブルクリックすると新しいウィンドウでエディタを開くことが出来ます。&lt;br /&gt;
複数のノートを行き来する時に便利です。&lt;/p&gt;
&lt;h3&gt;アプリテーマ&lt;/h3&gt;
&lt;p&gt;まず、テーマ切り替えとしてライトモード・ダークモードを提供しています。
&lt;img src=&quot;light-dark.webp&quot; alt=&quot;Light &amp;amp; Dark&quot; /&gt;&lt;/p&gt;
&lt;p&gt;さらに、デフォルトテーマとして「グレー」と「パープル」の2種類を提供しています。
&lt;img src=&quot;purple.webp&quot; alt=&quot;purple&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;カスタムテーマ&lt;/h4&gt;
&lt;p&gt;デフォルトテーマ以外に、公式テーマとして4種類のカスタムテーマを提供しています。
詳しくは以下のNotyraドキュメントページをご覧ください。&lt;/p&gt;
&lt;p&gt;https://notyra.y-shin.net/docs/theme/custom-theme&lt;/p&gt;
&lt;h2&gt;技術的なお話&lt;/h2&gt;
&lt;p&gt;ここから先はNotyraの中身に興味がある方向けです。&lt;/p&gt;
&lt;h3&gt;フレームワーク&lt;/h3&gt;
&lt;p&gt;元々v1ではElectronで開発していましたが、アプリ自体の容量が大きく起動も遅いためv2からはフレームワークをTauriに変更しました。&lt;br /&gt;
ElectronからTauriに変更したことでCPU使用率も低く、メモリ消費も40MB程度で抑えることが出来ました。&lt;br /&gt;
アプリ容量も数百MBから15MB程度まで減らすことが出来、個人的には満足しています。&lt;/p&gt;
&lt;p&gt;https://v2.tauri.app/ja/start/&lt;/p&gt;
&lt;h3&gt;画像の扱い方&lt;/h3&gt;
&lt;p&gt;Notyraでは画像の描画もサポートしています。
画像の挿入方法は以下の3種類をサポートしています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ドラッグ&amp;amp;ドロップ (複数可)&lt;/li&gt;
&lt;li&gt;クリップボードから (コピペ)&lt;/li&gt;
&lt;li&gt;画像挿入ボタンからの挿入 (複数可)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;画像の扱い方はかなり悩みました。ローカルで動作させるにはルートディレクトリ内で画像を管理する必要があるためです。&lt;br /&gt;
チャッピー(Chat GPT)と壁打ちしながら方法を考えた結果、ルートディレクトリ内に画像専用のディレクトリ(image)を作成し、Markdownファイルの中で利用されている画像のみをimageディレクトリの中に保存することにしました。
&lt;code&gt;Ctrl + Z&lt;/code&gt;で変更を戻す、貼り付け場所を誤る、間違った画像をアップロードするといった動作も多いと思うので、アプリの終了操作をしたタイミングで画像ファイルのクリーンアッププロセスを走らせ、Markdownファイル内で使用されていない画像を削除することにしました。&lt;/p&gt;
&lt;h3&gt;レンダリング速度&lt;/h3&gt;
&lt;p&gt;ノートリストには仮想スクロール(react-virtual)を導入しています。
1万を超えるノートもスムーズに描画することが出来ます。&lt;/p&gt;
&lt;p&gt;https://github.com/TanStack/virtual&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;今回はTauriでデスクトップアプリを開発してみたというお話でした。&lt;br /&gt;
久しぶりのデスクトップアプリの開発でしたが、生成AIが優秀で昔のようにGoogleで数十のタブを開きながら開発というのはなくなりましたね。&lt;/p&gt;
&lt;p&gt;Tauriは軽量かつ高速で、個人開発のデスクトップアプリのフレームワークとしては非常に優秀だと感じました。&lt;br /&gt;
Electronからの移行で体感できるほどパフォーマンスが改善されたのは純粋に嬉しかったです。&lt;/p&gt;
&lt;p&gt;Notyraはフィードバックがあれば機能追加・改善を続けていく予定です。&lt;br /&gt;
もし使ってみて気になった点や要望があれば、コメントやGitHubのIssueでお気軽にお声がけください。&lt;/p&gt;
&lt;p&gt;では、また。&lt;/p&gt;
</content:encoded></item><item><title>結局Fuwariに戻ってきた</title><link>https://www.y-shin.net/posts/comeback-fuwari/</link><guid isPermaLink="true">https://www.y-shin.net/posts/comeback-fuwari/</guid><description>右往左往した本サイトのデザインですが結局Fuwariに戻ってきました。</description><pubDate>Sat, 28 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;お久しぶりです。
この件に関しては投稿する予定はなかったのですが、年度末ということもあり投げておくことにしました。&lt;/p&gt;
&lt;p&gt;本サイトのデザインテンプレートはFuwariとYukinaを組み合わせたテンプレートである&lt;code&gt;Mizuki&lt;/code&gt;を利用していましたが、結局Fuwariに戻すことにしました。&lt;/p&gt;
&lt;h2&gt;戻ったきっかけ&lt;/h2&gt;
&lt;p&gt;Mizukiはページアニメーションも好みで見栄えがとても良いデザインで気に入っていたのですが、最近実装される機能が自分の求める方向と少し異なってきているようで、「使うかも」という安易な気持ちで新機能を取り入れていましたが、結局使わない機能がどんどん増えてページが重くなっていました。
このことをきっかけに、改めてテンプレートをどうするか考え直すことにしました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Webサイトのカテゴリは「ポートフォリオ」なので、マーケティングサイトのような派手なアニメーションは不要と整理しました&lt;/li&gt;
&lt;li&gt;ページ遷移時に退屈させないよう、遷移アニメーションだけは残したい&lt;/li&gt;
&lt;li&gt;サイト全体を軽くしたい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの条件を整理した結果、「Fuwariでいいや」という結論になり、戻ってくることにしました。
一応技術ブログを名乗っているので、記事を読んでいる途中でアニメーションやサイドバーのオブジェクトが邪魔になるのも良くないと感じています。&lt;/p&gt;
&lt;h2&gt;戻ってくるにあたって&lt;/h2&gt;
&lt;p&gt;Fuwariに戻すにあたって、まずWorkページのデザインを刷新しました。
以前のデザインはオブジェクト同士が窮屈で見づらく、モバイル表示ではレイアウト崩れも起きていたため、Card方式に変更しオブジェクト間のスペースも広く確保しました。&lt;/p&gt;
&lt;p&gt;次にAwardsページはMizuki時代のデザインをそのまま流用しました。
時系列がぱっと見てわかりやすいデザインが気に入っています。&lt;/p&gt;
&lt;p&gt;最後にUsesページですが、このページは廃止しました。
あまり更新しないことと、画像がほとんどAI生成の猫ちゃんだったので、画像を用意する気力が湧いたタイミングで改めて追加しようと思います。&lt;/p&gt;
&lt;p&gt;またサイト名は左上に移動しました。&lt;/p&gt;
&lt;p&gt;テーマカラーはFuwariデフォルトのブルー(250)を標準設定にしました。やはり寒色は落ち着きます。
グリーンはダークモードだと映えるのですが、ライトモードのグリーンはあまり好みではなかったというのもあります。
これから暑くなる季節でもありますしね。&lt;/p&gt;
&lt;h2&gt;最後に&lt;/h2&gt;
&lt;p&gt;Fuwariに戻してみましたが、Fuwariプロジェクトは最近あまり活発でないようです。(PRはたくさん起票されていますが)
テンプレートのライブラリが古く、かなりの脆弱性がそのままになっていました。
手動でバージョンを上げれば良いのと、メジャーバージョンアップ時は関連箇所を修正すれば良いだけなのですが。&lt;br /&gt;
このテンプレートを無料で提供していただいているので自分は何も言えないです。&lt;/p&gt;
</content:encoded></item><item><title>本サイトの名前が決まりました</title><link>https://www.y-shin.net/posts/yumrith/</link><guid isPermaLink="true">https://www.y-shin.net/posts/yumrith/</guid><description>まったりマイペースで更新してきた本サイトの名前が決まりました。</description><pubDate>Tue, 04 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;こんにちは。お久しぶりです。&lt;br /&gt;
9月、10月は人生において大きなターニングポイントがあり忙しかったですが、ようやく落ち着き始めました。(また記事にしようと思います。)&lt;br /&gt;
11月に入り一気に寒くなり体調を崩しかけましたが、なんとか持ち直しました。&lt;br /&gt;
インフルエンザも流行りだしているそうなので注意しないとですね。&lt;/p&gt;
&lt;h1&gt;サイト名&lt;/h1&gt;
&lt;p&gt;さて、数年前から始めた本サイトですが、そろそろ名前を決めねばと思い、生成AIの力も借りながらようやく名前が決まりました。&lt;/p&gt;
&lt;p&gt;サイト名は&amp;lt;h1&amp;gt;Yumrith（ユムリス）&amp;lt;/h1&amp;gt;と言います。&lt;/p&gt;
&lt;p&gt;元々本名をサイト名にしていたので、本名もちょこっと入れつつ技術的な用語も入れた名前が良いなと考えていました。&lt;br /&gt;
&lt;code&gt;Yuma + Algorithm&lt;/code&gt;を組み合わせた造語です。&lt;/p&gt;
&lt;p&gt;世の中で使われていない名前というのが難しく、この辺りはChat GPTのWeb Searchの力もお借りしました。&lt;/p&gt;
&lt;p&gt;中身は更新しないのに外側だけは頻繁に変えている私ですので、他のサイト名に変わるかもしれませんが、しばらくはこのままで行こうと思います。&lt;/p&gt;
&lt;p&gt;一応生成AIにロゴも考えてもらいましたが、これは多分使わないと思います。&lt;br /&gt;
このポストのサムネイルにしておきます。&lt;/p&gt;
&lt;h1&gt;サイトデザイン&lt;/h1&gt;
&lt;p&gt;サイトのデザインもちょこっと変更しました。&lt;br /&gt;
FuwariというAstroテンプレートを使用していましたが、Mizukiというテンプレートを発見しこちらに変更しました。&lt;/p&gt;
&lt;p&gt;元々、FuwariとYukinaを組み合わせて独自デザインにしていましたが、FuwariとYukinaを組み合わせたものがテンプレートとしてリリースされており、それが&lt;code&gt;Mizuki&lt;/code&gt;です。&lt;/p&gt;
&lt;p&gt;https://astro.build/themes/details/mizuki/&lt;/p&gt;
&lt;p&gt;Fuwariだけではサイトの動きが少なくさみしい印象で、Yukinaだけだと少し機能不足だなと思っていて、かゆいところに手の届くMizukiはとてもありがたいテンプレートです。&lt;br /&gt;
Fuwariファミリーですので、見た目に大きな変更はありません。&lt;/p&gt;
&lt;h1&gt;最後に&lt;/h1&gt;
&lt;p&gt;人生において大きなターニングポイントというのは「転職」でした。&lt;br /&gt;
フルリモート勤務からフル出社勤務になり、ワークライフバランスが大きく変わることとなりました。&lt;/p&gt;
&lt;p&gt;前職では新入社員に環境の変化は無意識のうちにストレスとして蓄積されていると伝えていました。&lt;br /&gt;
自分がこの立場になり、ストレスの自覚は無いですが、無意識のうちに蓄積されていると思うので焦らずゆっくり慣れていこうと思います。&lt;/p&gt;
</content:encoded></item><item><title>FuwariでExpressive Codeを使用しコードブロックをカスタマイズする</title><link>https://www.y-shin.net/posts/fuwari-expressive-code/</link><guid isPermaLink="true">https://www.y-shin.net/posts/fuwari-expressive-code/</guid><description>FuwariでExpressive Codeを使用しコードブロックをカスタマイズしてみました。</description><pubDate>Sun, 02 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::warning
2025-06-07&lt;br /&gt;
&lt;a href=&quot;https://github.com/saicaca/fuwari/pull/476&quot;&gt;#476&lt;/a&gt;でExpressive Codeが公式サポートされ、
最新のfuwariテンプレートではこの手順は不要となりました。
:::&lt;/p&gt;
&lt;p&gt;FuwariのデフォルトコードブロックはLanguageやファイル名を表示できないため、&lt;code&gt;astro-expressive-code&lt;/code&gt;を利用してカスタマイズしてみました。&lt;/p&gt;
&lt;h1&gt;Expressive Codeとは&lt;/h1&gt;
&lt;p&gt;Expressive Code は、開発者がコードスニペットを美しく、分かりやすく表示できるようにするためのライブラリです。Markdownベースのドキュメント、ブログ、技術記事などで、コードの見た目を改善するために活用されます。&lt;/p&gt;
&lt;p&gt;このライブラリは プラグインベースの設計 になっており、カスタマイズ性が高いのが特徴です。&lt;/p&gt;
&lt;p&gt;https://expressive-code.com/&lt;/p&gt;
&lt;h1&gt;インストール方法&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;以下のコマンドで&lt;code&gt;astro-expressive-code&lt;/code&gt;と&lt;code&gt;@expressive-code/plugin-line-numbers&lt;/code&gt;をインストールする&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;pnpm add astro-expressive-code @expressive-code/plugin-line-numbers
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;astro.config.mjs&lt;/code&gt;で定義する&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;import expressiveCode from &quot;astro-expressive-code&quot;;
import { pluginLineNumbers } from &quot;@expressive-code/plugin-line-numbers&quot;;
import remnarkLinkCard from &quot;remark-link-card&quot;;

// https://astro.build/config
export default defineConfig({
  site: &quot;https://www.y-shin.net/&quot;,
  base: &quot;/&quot;,
  trailingSlash: &quot;always&quot;,
  integrations: [
    tailwind({
      nesting: true,
    }),
    swup({
      theme: false,
      animationClass: &quot;transition-swup-&quot;, // see https://swup.js.org/options/#animationselector
      // the default value `transition-` cause transition delay
      // when the Tailwind class `transition-all` is used
      containers: [&quot;main&quot;, &quot;#toc&quot;],
      smoothScrolling: true,
      cache: true,
      preload: true,
      accessibility: true,
      updateHead: true,
      updateBodyClass: false,
      globalInstance: true,
    }),
    icon({
      include: {
        &quot;preprocess: vitePreprocess(),&quot;: [&quot;*&quot;],
        &quot;fa6-brands&quot;: [&quot;*&quot;],
        &quot;fa6-regular&quot;: [&quot;*&quot;],
        &quot;fa6-solid&quot;: [&quot;*&quot;],
      },
    }),
    svelte(),
    sitemap(),
    Compress({
      CSS: false,
      Image: false,
      Action: {
        Passed: async () =&amp;gt; true, // https://github.com/PlayForm/Compress/issues/376
      },
    }),
    expressiveCode({
      themes: [&quot;aurora-x&quot;],
      plugins: [pluginLineNumbers()],
    }),
  ],
  markdown: {
    remarkPlugins: [[remnarkLinkCard, { shortenUrl: true, cache: true }], remarkMath, remarkReadingTime, remarkExcerpt, remarkGithubAdmonitionsToDirectives, remarkDirective, remarkSectionize, parseDirectiveNode],
    rehypePlugins: [
      rehypeKatex,
      rehypeSlug,
      [
        rehypeComponents,
        {
          components: {
            github: GithubCardComponent,
            linkcard: LinkCardComponent,
            note: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;note&quot;),
            tip: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;tip&quot;),
            important: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;important&quot;),
            caution: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;caution&quot;),
            warning: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;warning&quot;),
          },
        },
      ],
      [
        rehypeAutolinkHeadings,
        {
          behavior: &quot;append&quot;,
          properties: {
            className: [&quot;anchor&quot;],
          },
          content: {
            type: &quot;element&quot;,
            tagName: &quot;span&quot;,
            properties: {
              className: [&quot;anchor-icon&quot;],
              &quot;data-pagefind-ignore&quot;: true,
            },
            children: [
              {
                type: &quot;text&quot;,
                value: &quot;#&quot;,
              },
            ],
          },
        },
      ],
    ],
  },
  vite: {
    build: {
      rollupOptions: {
        onwarn(warning, warn) {
          // temporarily suppress this warning
          if (warning.message.includes(&quot;is dynamically imported by&quot;) &amp;amp;&amp;amp; warning.message.includes(&quot;but also statically imported by&quot;)) {
            return;
          }
          warn(warning);
        },
      },
    },
  },
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;既存スクリプトの編集&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;src/layouts/Layout.astro&lt;/code&gt;で&lt;code&gt;preElements&lt;/code&gt;を削除する&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;function initCustomScrollbar() {
	const bodyElement = document.querySelector(&apos;body&apos;);
	if (!bodyElement) return;
	OverlayScrollbars(
		// docs say that a initialization to the body element would affect native functionality like window.scrollTo
		// but just leave it here for now
		{
			target: bodyElement,
			cancel: {
				nativeScrollbarsOverlaid: true,    // don&apos;t initialize the overlay scrollbar if there is a native one
			}
		}, {
		scrollbars: {
			theme: &apos;scrollbar-base scrollbar-auto py-1&apos;,
			autoHide: &apos;move&apos;,
			autoHideDelay: 500,
			autoHideSuspend: false,
		},
	});
	const preElements = document.querySelectorAll(&apos;pre&apos;);
	preElements.forEach((ele) =&amp;gt; {
		OverlayScrollbars(ele, {
			scrollbars: {
				theme: &apos;scrollbar-base scrollbar-dark px-2&apos;,
				autoHide: &apos;leave&apos;,
				autoHideDelay: 500,
				autoHideSuspend: false
			}
		});
	});
	const katexElements = document.querySelectorAll(&apos;.katex-display&apos;) as NodeListOf&amp;lt;HTMLElement&amp;gt;;
	katexElements.forEach((ele) =&amp;gt; {
		OverlayScrollbars(ele, {
			scrollbars: {
				theme: &apos;scrollbar-base scrollbar-auto py-1&apos;,
			}
		});
	});
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;src/component/misc/Markdown.astro&lt;/code&gt;を編集し、コピーボタンのスクリプトを削除する。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;---
import &apos;@fontsource-variable/jetbrains-mono&apos;
import &apos;@fontsource-variable/jetbrains-mono/wght-italic.css&apos;

interface Props {
  class: string
}
const className = Astro.props.class
---
&amp;lt;div data-pagefind-body class=`prose dark:prose-invert prose-base !max-w-none custom-md ${className}`&amp;gt;
    &amp;lt;!--&amp;lt;div class=&quot;prose dark:prose-invert max-w-none custom-md&quot;&amp;gt;--&amp;gt;
    &amp;lt;!--&amp;lt;div class=&quot;max-w-none custom-md&quot;&amp;gt;--&amp;gt;
    &amp;lt;slot/&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
    let linkCards = Array.from(document.querySelectorAll(&quot;.rlc-container&quot;)) as HTMLElement[];
    for (let linkCard of linkCards) {
        linkCard.classList.add(&quot;no-styling&quot;);
        linkCard.style.textDecoration = &quot;none&quot;;
        linkCard.setAttribute(&apos;target&apos;,&apos;_blank&apos;);
    }
&amp;lt;/script&amp;gt;

&amp;lt;script&amp;gt;
  const observer = new MutationObserver(addPreCopyButton);
  observer.observe(document.body, { childList: true, subtree: true });

  document.addEventListener(&quot;DOMContentLoaded&quot;, addPreCopyButton);

  function addPreCopyButton() {
    observer.disconnect();

    let codeBlocks = Array.from(document.querySelectorAll(&quot;pre&quot;));

    for (let codeBlock of codeBlocks) {
      if (codeBlock.parentElement?.nodeName === &quot;DIV&quot; &amp;amp;&amp;amp; codeBlock.parentElement?.classList.contains(&quot;code-block&quot;)) continue

      let wrapper = document.createElement(&quot;div&quot;);
      wrapper.className = &quot;relative code-block&quot;;

      let copyButton = document.createElement(&quot;button&quot;);
      copyButton.className = &quot;copy-btn btn-regular-dark absolute active:scale-90 h-8 w-8 top-2 right-2 opacity-75 text-sm p-1.5 rounded-lg transition-all ease-in-out&quot;;

      codeBlock.setAttribute(&quot;tabindex&quot;, &quot;0&quot;);
      if (codeBlock.parentNode) {
        codeBlock.parentNode.insertBefore(wrapper, codeBlock);
      }

      let copyIcon = `&amp;lt;svg class=&quot;copy-btn-icon copy-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; height=&quot;20px&quot; viewBox=&quot;0 -960 960 960&quot; width=&quot;20px&quot;&amp;gt;&amp;lt;path d=&quot;M368.37-237.37q-34.48 0-58.74-24.26-24.26-24.26-24.26-58.74v-474.26q0-34.48 24.26-58.74 24.26-24.26 58.74-24.26h378.26q34.48 0 58.74 24.26 24.26 24.26 24.26 58.74v474.26q0 34.48-24.26 58.74-24.26 24.26-58.74 24.26H368.37Zm0-83h378.26v-474.26H368.37v474.26Zm-155 238q-34.48 0-58.74-24.26-24.26-24.26-24.26-58.74v-515.76q0-17.45 11.96-29.48 11.97-12.02 29.33-12.02t29.54 12.02q12.17 12.03 12.17 29.48v515.76h419.76q17.45 0 29.48 11.96 12.02 11.97 12.02 29.33t-12.02 29.54q-12.03 12.17-29.48 12.17H213.37Zm155-238v-474.26 474.26Z&quot;/&amp;gt;&amp;lt;/svg&amp;gt;`
      let successIcon = `&amp;lt;svg class=&quot;copy-btn-icon success-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; height=&quot;20px&quot; viewBox=&quot;0 -960 960 960&quot; width=&quot;20px&quot;&amp;gt;&amp;lt;path d=&quot;m389-377.13 294.7-294.7q12.58-12.67 29.52-12.67 16.93 0 29.61 12.67 12.67 12.68 12.67 29.53 0 16.86-12.28 29.14L419.07-288.41q-12.59 12.67-29.52 12.67-16.94 0-29.62-12.67L217.41-430.93q-12.67-12.68-12.79-29.45-.12-16.77 12.55-29.45 12.68-12.67 29.62-12.67 16.93 0 29.28 12.67L389-377.13Z&quot;/&amp;gt;&amp;lt;/svg&amp;gt;`
      copyButton.innerHTML = `&amp;lt;div&amp;gt;${copyIcon} ${successIcon}&amp;lt;/div&amp;gt;
      `

      wrapper.appendChild(codeBlock);
      wrapper.appendChild(copyButton);

      let timeout: ReturnType&amp;lt;typeof setTimeout&amp;gt;;
      copyButton.addEventListener(&quot;click&quot;, async () =&amp;gt; {
        if (timeout) {
            clearTimeout(timeout);
        }
        let text = codeBlock?.querySelector(&quot;code&quot;)?.innerText;
        if (text === undefined) return;
        await navigator.clipboard.writeText(text);
        copyButton.classList.add(&quot;success&quot;);
        timeout = setTimeout(() =&amp;gt; {
          copyButton.classList.remove(&quot;success&quot;);
        }, 1000);
      });
    }

    observer.observe(document.body, { childList: true, subtree: true });
  }
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Fuwariでremark-link-cardを使用してリンクカードを実装する</title><link>https://www.y-shin.net/posts/fuwari-link-card/</link><guid isPermaLink="true">https://www.y-shin.net/posts/fuwari-link-card/</guid><description>Fuwariでremark-link-cardを使用してリンクカードを実装してみました</description><pubDate>Sun, 02 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;FuwariではリンクカードはGithubのみの対応のため、その他のサイトもリンクカードとして表示させるカスタマイズを入れました。&lt;br /&gt;
AstroではRemark Pluginが使用できるため、今回は定番のremark-link-cardを使用しました。&lt;/p&gt;
&lt;h1&gt;remark-link-cardとは&lt;/h1&gt;
&lt;p&gt;​remark-link-cardは、Markdown内のテキストリンクをカード形式に変換するためのremarkプラグインです。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;gladevise/remark-link-card&quot;}&lt;/p&gt;
&lt;h1&gt;インストール方法&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;remark-link-card&lt;/code&gt;をインストールする。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;pnpm add remark-link-card
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;astro.config.mjs&lt;/code&gt;でremark-link-cardを定義します。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;import remnarkLinkCard from &apos;remark-link-card&apos;
{/* 中略 */}
remarkPlugins: [
      [remnarkLinkCard,{ shortenUrl: true }],
      remarkMath,
      remarkReadingTime,
      remarkExcerpt,
      remarkGithubAdmonitionsToDirectives,
      remarkDirective,
      remarkSectionize,
      parseDirectiveNode,
    ],
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;既存のスクリプトを編集する&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;src/styles/markdown.css&lt;/code&gt;でremark-link-cardのStyleを追記する。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;.rlc-container {
  width: 100%;
  max-width: 800px;
  max-height: 130px;
  margin: 0 auto 2rem;
  background: var(--license-block-bg);

  text-decoration: none;

  border-radius: 0.75rem;
  display: flex;
  align-items: stretch;
  flex-direction: row; /* デフォルトは横並び */

  transition:
    background 200ms ease-in-out 0s,
    box-shadow 200ms ease-in-out 0s;
}

.rlc-container:hover {
  background-color: var(--btn-regular-bg-hover);
}

.rlc-info {
  overflow: hidden; /* PCではhidden */
  padding: 1rem;
  text-align: left;
  flex: 4 1 100px;
  align-items: flex-start;
  text-decoration: none;
  min-height: 100px; /* スマホ時に高さ不足にならないように */
}

.rlc-title {
  font-size: 1.25rem;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

/* PCでは1行で「...」 */
.rlc-description {
  font-size: 0.875rem;
  font-weight: 300;
  display: -webkit-box;
  -webkit-line-clamp: 1; /* 1行で省略 */
  -webkit-box-orient: vertical;
  text-overflow: ellipsis;
  line-height: 1.4rem; /* 行の高さを適切に調整 */
  max-height: 3rem;
  overflow: hidden;
  flex-grow: 1; /* 説明文が途切れないように */
  padding-bottom: 4px; /* PC時の圧迫を防ぐ */
  color: var(--tw-prose-body);
}

.rlc-url-container {
  margin-top: auto; /* 説明文の下に配置 */
  display: flex;
  align-items: center;
}

.rlc-favicon {
  margin-right: 4px;
  width: 16px;
  height: 16px;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
}

.rlc-url {
  font-size: 1rem;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

.rlc-image-container {
  position: relative;
  flex: 1 1 100px;
  padding: 0.3rem;
  aspect-ratio: 1 / 1;
}

.rlc-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-bottom-right-radius: 0.25rem;
  border-top-right-radius: 0.25rem;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
}

/* スマホ用のレイアウト調整 */
@media (max-width: 768px) {
  .rlc-container {
    flex-direction: column;
    max-height: unset;
  }

  /* 画像を上にする */
  .rlc-image-container {
    order: -1;
    flex: none;
    width: 100%;
    /*height: 150px;*/
    padding: 0.5rem;
    aspect-ratio: 1.91 / 1;
  }

  .rlc-image {
    width: 100%;
    height: 100%;
    border-radius: 0.75rem 0.75rem 0 0;
  }

  /* スマホではタイトル・説明・URLを折り返す */
  .rlc-title {
    white-space: normal;
    overflow: visible;
  }

  /* スマホでは全文表示 */
  .rlc-description {
    -webkit-line-clamp: unset; /* 制限解除 */
    -webkit-box-orient: unset;
    display: block;
    max-height: none;
    height: auto;
    overflow: visible;
    flex-grow: unset; /* スマホでは自由に伸ばす */
  }

  .rlc-info {
    overflow: visible; /* スマホではhiddenを解除 */
    min-height: unset; /* スマホでは高さ制限を解除 */
  }

  .rlc-url {
    white-space: normal;
    overflow-wrap: break-word;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;src/components/misc/Markdown.astro&lt;/code&gt;でリンクカードに対してTailwind CSS (prose)を適用させないようにする。&lt;br /&gt;
scriptタグの中に以下を追記する。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;let linkCards = Array.from(document.querySelectorAll(&quot;.rlc-container&quot;)) as HTMLElement[];
for (let linkCard of linkCards) {
    linkCard.classList.add(&quot;no-styling&quot;); // Tailwind CSS(prose)を適用させないようにする
    linkCard.style.textDecoration = &quot;none&quot;; // 文字列の下線部を非表示にする
    linkCard.setAttribute(&apos;target&apos;,&apos;_blank&apos;); //新しいタブで開く
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;参考にさせて頂いたありがたいサイト&lt;/h1&gt;
&lt;p&gt;https://sur33.com/posts/remark-link-card-with-astro/&lt;/p&gt;
</content:encoded></item><item><title>個人WEBをAstro + Fuwariで書き直しました</title><link>https://www.y-shin.net/posts/rewrite-astro/</link><guid isPermaLink="true">https://www.y-shin.net/posts/rewrite-astro/</guid><description>個人WEBをAstro + Fuwariで書き直しました</description><pubDate>Fri, 28 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;個人WEBをTailwind CSSで書き直して約半年...&lt;br /&gt;
また、書き直してしまいました...&lt;/p&gt;
&lt;p&gt;今回は今ホットなAstroで個人WEBをリメイクしました。&lt;/p&gt;
&lt;p&gt;テンプレートはAstro公式サイトでビビッと来た&lt;code&gt;Fuwari&lt;/code&gt;を使用しました。&lt;br /&gt;
デザインがとても良く、かゆいところにも手が届いており無料で利用できることに驚いています。&lt;/p&gt;
&lt;p&gt;https://astro.build/themes/details/fuwari/&lt;/p&gt;
&lt;h1&gt;Astroとは&lt;/h1&gt;
&lt;p&gt;Astroは、 &lt;strong&gt;静的サイトジェネレーター（SSG）とサーバーレンダリング（SSR）&lt;/strong&gt; の両方をサポートする、次世代のフロントエンドフレームワークです。軽量で高速なWebサイトを構築することを目的とし、 &lt;strong&gt;コンテンツ中心のWebサイト（ブログ、ドキュメント、マーケティングサイトなど）&lt;/strong&gt; に最適です。&lt;/p&gt;
&lt;p&gt;表示も早いですが、体感ビルドも早い気がします。&lt;/p&gt;
&lt;p&gt;また、Astroは &lt;strong&gt;Markdown（.md）とMDX（.mdx）&lt;/strong&gt; をネイティブサポートしており、ブログやドキュメントサイトの構築が容易です。&lt;/p&gt;
&lt;p&gt;https://astro.build/&lt;/p&gt;
&lt;h1&gt;Fuwariとは&lt;/h1&gt;
&lt;p&gt;FuwariはAstroの&lt;a href=&quot;https://astro.build/themes/&quot;&gt;Themes&lt;/a&gt;で公開されているブログテンプレートの1つです。&lt;br /&gt;
Fuwariのリポジトリで右上の&lt;code&gt;Use this template&lt;/code&gt;をクリックすることで自分のリポジトリに複製することが出来ます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AstroとTailwind CSSで設計&lt;/li&gt;
&lt;li&gt;Swupで設計されたスムーズなアニメーションとページ遷移&lt;/li&gt;
&lt;li&gt;ライト / ダークモード&lt;/li&gt;
&lt;li&gt;カスタマイズ可能なテーマカラーとバナー&lt;/li&gt;
&lt;li&gt;レスポンシブデザイン&lt;/li&gt;
&lt;li&gt;Pagefindによる検索&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ユーザ側でテーマカラーを自由に変更できる機能がユニークで面白いですね。&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;saicaca/fuwari&quot;}&lt;/p&gt;
&lt;h1&gt;サイトのカスタマイズ&lt;/h1&gt;
&lt;p&gt;サイトの設定を編集する際は&lt;code&gt;src/config.ts&lt;/code&gt;を直接変更します。&lt;br /&gt;
サイトタイトルやプロフィール画像、テーマカラーの変更などが出来ます。&lt;/p&gt;
&lt;p&gt;この他に本WEBサイトでは、以下のカスタマイズを入れています。&lt;/p&gt;
&lt;h2&gt;リンクカード&lt;/h2&gt;
&lt;p&gt;FuwariではリンクカードはGithubのみの対応のため、その他のサイトもリンクカードとして表示させるカスタマイズを入れました。&lt;br /&gt;
AstroではRemark Pluginが使用できるため、今回は定番の&lt;code&gt;remark-link-card&lt;/code&gt;を使用しました。&lt;/p&gt;
&lt;p&gt;以下で記事にしています。&lt;/p&gt;
&lt;p&gt;https://www.y-shin.net/posts/fuwari-link-card/&lt;/p&gt;
&lt;h2&gt;ブログページにコメント機能をつける&lt;/h2&gt;
&lt;p&gt;コメント機能はこれまでと同様に&lt;code&gt;giscus&lt;/code&gt;を使用しました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;以下の手順でgiscusを使用するための準備をする&lt;br /&gt;
&lt;a href=&quot;/posts/giscus-nextjs/#giscus%E3%81%AE%E8%A8%AD%E5%AE%9A&quot;&gt;giscusの設定&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;src/components/Comments.astro&lt;/code&gt;を作成する&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;section&amp;gt;
  &amp;lt;script src=&quot;https://giscus.app/client.js&quot;
      is:inline
      data-repo={import.meta.env.NEXT_PUBLIC_GISCUS_REPO}
      data-repo-id={import.meta.env.NEXT_PUBLIC_GISCUS_REPO_ID}
      data-category=&quot;Announcements&quot;
      data-category-id={import.meta.env.NEXT_PUBLIC_GISCUS_CATEGORY_ID}
      data-mapping=&quot;pathname&quot;
      data-strict=&quot;0&quot;
      data-reactions-enabled=&quot;1&quot;
      data-emit-metadata=&quot;0&quot;
      data-input-position=&quot;bottom&quot;
      data-lang=&quot;ja&quot;
      crossorigin=&quot;anonymous&quot;
      data-theme=&quot;preferred_color_scheme&quot;
      async&amp;gt;
  &amp;lt;/script&amp;gt;
&amp;lt;/section&amp;gt;

&amp;lt;script is:inline&amp;gt;
  function updateGiscusTheme() {
    const theme = document.documentElement.classList.contains(&apos;dark&apos;) ? &apos;dark&apos; : &apos;light&apos;
    const iframe = document.querySelector(&apos;iframe.giscus-frame&apos;)
    if (!iframe) return
    iframe.contentWindow.postMessage({ giscus: { setConfig: { theme } } }, &apos;https://giscus.app&apos;)
  }

  const observer = new MutationObserver(updateGiscusTheme)
  observer.observe(document.documentElement, { attributes: true, attributeFilter: [&apos;class&apos;] })

  window.onload = () =&amp;gt; {
    updateGiscusTheme()
  }
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;.env.local&lt;/code&gt;を作成する&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;NEXT_PUBLIC_GISCUS_REPO={repository_name}
NEXT_PUBLIC_GISCUS_REPO_ID={repository_id}
NEXT_PUBLIC_GISCUS_CATEGORY_ID={category_id}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;src/pages/posts/[...slug].astro&lt;/code&gt;に作成した&lt;code&gt;Comments&lt;/code&gt;コンポーネントを追加する&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;import Comments from &apos;../../components/Comments.astro&apos;;
{/* 中略 */}
&amp;lt;div class=&quot;flex flex-col md:flex-row justify-between mb-4 gap-4 overflow-hidden w-full&quot;&amp;gt;
    &amp;lt;a href={entry.data.nextSlug ? getPostUrlBySlug(entry.data.nextSlug) : &quot;#&quot;}
        class:list={[&quot;w-full font-bold overflow-hidden active:scale-95&quot;, {&quot;pointer-events-none&quot;: !entry.data.nextSlug}]}&amp;gt;
        {entry.data.nextSlug &amp;amp;&amp;amp; &amp;lt;div class=&quot;btn-card rounded-2xl w-full h-[3.75rem] max-w-full px-4 flex items-center !justify-start gap-4&quot; &amp;gt;
            &amp;lt;Icon name=&quot;material-symbols:chevron-left-rounded&quot; class=&quot;text-[2rem] text-[var(--primary)]&quot; /&amp;gt;
            &amp;lt;div class=&quot;overflow-hidden transition overflow-ellipsis whitespace-nowrap max-w-[calc(100%_-_3rem)] text-black/75 dark:text-white/75&quot;&amp;gt;
                {entry.data.nextTitle}
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;}
    &amp;lt;/a&amp;gt;

    &amp;lt;a href={entry.data.prevSlug ? getPostUrlBySlug(entry.data.prevSlug) : &quot;#&quot;}
        class:list={[&quot;w-full font-bold overflow-hidden active:scale-95&quot;, {&quot;pointer-events-none&quot;: !entry.data.prevSlug}]}&amp;gt;
        {entry.data.prevSlug &amp;amp;&amp;amp; &amp;lt;div class=&quot;btn-card rounded-2xl w-full h-[3.75rem] max-w-full px-4 flex items-center !justify-end gap-4&quot;&amp;gt;
            &amp;lt;div class=&quot;overflow-hidden transition overflow-ellipsis whitespace-nowrap max-w-[calc(100%_-_3rem)] text-black/75 dark:text-white/75&quot;&amp;gt;
                {entry.data.prevTitle}
            &amp;lt;/div&amp;gt;
            &amp;lt;Icon name=&quot;material-symbols:chevron-right-rounded&quot; class=&quot;text-[2rem] text-[var(--primary)]&quot; /&amp;gt;
        &amp;lt;/div&amp;gt;}
    &amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div class=&quot;card-base z-10 px-3 md:px-6 pt-6 pb-4 relative w-full&quot;&amp;gt;
    &amp;lt;Comments /&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;コードブロックのデザインを変更する&lt;/h2&gt;
&lt;p&gt;FuwariデフォルトのコードブロックはLanguageやファイル名を表示できないため、&lt;code&gt;astro-expressive-code&lt;/code&gt;を使用してカスタマイズしました。&lt;/p&gt;
&lt;p&gt;以下で記事にしています。&lt;/p&gt;
&lt;p&gt;https://www.y-shin.net/posts/fuwari-expressive-code/&lt;/p&gt;
&lt;h1&gt;おわりに&lt;/h1&gt;
&lt;p&gt;Astroは今回のサイトのリメイクで初めて触れましたが、比較的入りやすかったです。&lt;br /&gt;
まだ深く理解できていないので今後も色々作りながら学んでいければと思っています。&lt;/p&gt;
&lt;h1&gt;参考にさせていただいたありがたいサイト&lt;/h1&gt;
&lt;p&gt;https://www.maxpou.fr/blog/giscus-with-astro/&lt;/p&gt;
</content:encoded></item><item><title>Oh My PoshでWindows Terminalをカスタマイズする(備忘録)</title><link>https://www.y-shin.net/posts/oh-my-posh/</link><guid isPermaLink="true">https://www.y-shin.net/posts/oh-my-posh/</guid><description>Oh My Poshを使用してWindows Terminalをカスタマイズする方法を備忘録として残しておきます。</description><pubDate>Tue, 25 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Oh My Poshとは&lt;/h1&gt;
&lt;p&gt;Oh My Posh は、Windows、Mac、Linux で使える シェルプロンプトのカスタマイズツール です。PowerShell、Bash、Zsh、Fish などに対応しており、カラフルで見やすいプロンプトを簡単に設定できます。&lt;/p&gt;
&lt;h1&gt;ディレクトリツリー&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;%USERPROFILE%
├── .config
│   ├── powershell
│   │   ├── user_profile.ps1
│   │   ├── user.omp.json
C:\
├── ドキュメント
│   ├── PowerShellMicrosoft.PowerShell_profile.ps1
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;1. Microsoft StoreでPowerShellをインストールする&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Micsoroft Store Appを開く&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;検索バーで&lt;code&gt;PowerShell&lt;/code&gt;と入力する&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;PowerShell&lt;/code&gt;をクリックし、&lt;code&gt;入手&lt;/code&gt;をクリックする&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;2. Nerd Font をインストールする&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;以下のリポジトリから&lt;code&gt;Hack.zip&lt;/code&gt;をダウンロードする&lt;br /&gt;
::github{repo=&quot;ryanoasis/nerd-fonts&quot;}&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ダウンロードしたZIPファイルを展開し、&lt;code&gt;HackNerdFontMono-Regular.ttf&lt;/code&gt;をダブルクリックし&lt;code&gt;インストール&lt;/code&gt;をクリックする
&lt;img src=&quot;./font.png&quot; alt=&quot;Font Install Window Test&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;3. Windows Terminalの設定を変更する&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ターミナル&lt;/code&gt;を開く&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;設定&lt;/code&gt;をクリックする&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;スタートアップ&lt;/code&gt;で規定のプロファイルを先程インストールした&lt;code&gt;PowerShell&lt;/code&gt;に変更する
&lt;img src=&quot;./terminal01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;プロファイルで&lt;code&gt;PowerShell&lt;/code&gt;を選択し、下部の&lt;code&gt;外観&lt;/code&gt;をクリックする
&lt;img src=&quot;./terminal02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;フォントフェイスを&lt;code&gt;Hack Nerd Font Mono&lt;/code&gt;に変更し&lt;code&gt;保存&lt;/code&gt;をクリックする
&lt;img src=&quot;./terminal03.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;4. Oh My Poshをインストールする&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;wingetを利用してOh My Poshをインストールする&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;winget install JanDeDobbeleer.OhMyPosh
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;%UserProfile%\.config\powershell&lt;/code&gt;に&lt;code&gt;user_profile.ps1&lt;/code&gt;を作成する&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以下のスクリプトをコピペする&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# set PowerShell to UTF-8
[console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding

# Prompt
$omp_config = Join-Path $PSScriptRoot &quot;.\user.omp.json&quot;
oh-my-posh --init --shell pwsh --config $omp_config | Invoke-Expression
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;%UserProfile%\.config\powershell&lt;/code&gt;に&lt;code&gt;user.omp.json&lt;/code&gt;を作成する&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以下のJSONをコピペする&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;$schema&quot;: &quot;https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json&quot;,
  &quot;blocks&quot;: [
    {
      &quot;type&quot;: &quot;prompt&quot;,
      &quot;alignment&quot;: &quot;left&quot;,
      &quot;segments&quot;: [
        {
          &quot;properties&quot;: {
            &quot;cache_duration&quot;: &quot;none&quot;
          },
          &quot;leading_diamond&quot;: &quot;\u256d\u2500\ue0b6&quot;,
          &quot;template&quot;: &quot; {{ .Name }} &quot;,
          &quot;foreground&quot;: &quot;#ffffff&quot;,
          &quot;background&quot;: &quot;#0077c2&quot;,
          &quot;type&quot;: &quot;shell&quot;,
          &quot;style&quot;: &quot;diamond&quot;
        },
        {
          &quot;properties&quot;: {
            &quot;cache_duration&quot;: &quot;none&quot;,
            &quot;root_icon&quot;: &quot;\uf292&quot;
          },
          &quot;template&quot;: &quot;&amp;lt;parentBackground&amp;gt;\ue0b0&amp;lt;/&amp;gt; \uf0e7 &quot;,
          &quot;foreground&quot;: &quot;#FFFB38&quot;,
          &quot;background&quot;: &quot;#ef5350&quot;,
          &quot;type&quot;: &quot;root&quot;,
          &quot;style&quot;: &quot;diamond&quot;
        },
        {
          &quot;properties&quot;: {
            &quot;cache_duration&quot;: &quot;none&quot;,
            &quot;enable_hyperlink&quot;: true,
            &quot;style&quot;: &quot;full&quot;
          },
          &quot;template&quot;: &quot; {{ .Path }} &quot;,
          &quot;foreground&quot;: &quot;#E4E4E4&quot;,
          &quot;powerline_symbol&quot;: &quot;\ue0b0&quot;,
          &quot;background&quot;: &quot;#444444&quot;,
          &quot;type&quot;: &quot;path&quot;,
          &quot;style&quot;: &quot;powerline&quot;
        },
        {
          &quot;properties&quot;: {
            &quot;branch_icon&quot;: &quot;\ue725 &quot;,
            &quot;cache_duration&quot;: &quot;none&quot;,
            &quot;fetch_status&quot;: true,
            &quot;fetch_upstream_icon&quot;: true
          },
          &quot;template&quot;: &quot; {{ .HEAD }} {{ if .Working.Changed }}{{ .Working.String }}{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }} |{{ end }}{{ if .Staging.Changed }}&amp;lt;#ef5350&amp;gt; \uf046 {{ .Staging.String }}&amp;lt;/&amp;gt;{{ end }} &quot;,
          &quot;foreground&quot;: &quot;#011627&quot;,
          &quot;powerline_symbol&quot;: &quot;\ue0b0&quot;,
          &quot;background&quot;: &quot;#FFFB38&quot;,
          &quot;type&quot;: &quot;git&quot;,
          &quot;style&quot;: &quot;powerline&quot;,
          &quot;background_templates&quot;: [&quot;{{ if or (.Working.Changed) (.Staging.Changed) }}#ffeb95{{ end }}&quot;, &quot;{{ if and (gt .Ahead 0) (gt .Behind 0) }}#c5e478{{ end }}&quot;, &quot;{{ if gt .Ahead 0 }}#C792EA{{ end }}&quot;, &quot;{{ if gt .Behind 0 }}#C792EA{{ end }}&quot;]
        }
      ]
    },
    {
      &quot;type&quot;: &quot;prompt&quot;,
      &quot;alignment&quot;: &quot;right&quot;,
      &quot;segments&quot;: [
        {
          &quot;properties&quot;: {
            &quot;cache_duration&quot;: &quot;none&quot;,
            &quot;fetch_package_manager&quot;: true,
            &quot;npm_icon&quot;: &quot; &amp;lt;#cc3a3a&amp;gt;\ue5fa&amp;lt;/&amp;gt; &quot;,
            &quot;yarn_icon&quot;: &quot; &amp;lt;#348cba&amp;gt;\uf61a&amp;lt;/&amp;gt;&quot;
          },
          &quot;leading_diamond&quot;: &quot; \ue0b6&quot;,
          &quot;trailing_diamond&quot;: &quot;\ue0b4&quot;,
          &quot;template&quot;: &quot;\ue718 {{ if .PackageManagerIcon }}{{ .PackageManagerIcon }} {{ end }}{{ .Full }}&quot;,
          &quot;foreground&quot;: &quot;#3C873A&quot;,
          &quot;background&quot;: &quot;#303030&quot;,
          &quot;type&quot;: &quot;node&quot;,
          &quot;style&quot;: &quot;diamond&quot;
        },
        {
          &quot;properties&quot;: {
            &quot;cache_duration&quot;: &quot;none&quot;,
            &quot;fetch_package_manager&quot;: true,
            &quot;npm_icon&quot;: &quot; &amp;lt;#cc3a3a&amp;gt;\ue5fa&amp;lt;/&amp;gt; &quot;,
            &quot;yarn_icon&quot;: &quot; &amp;lt;#348cba&amp;gt;\uf61a&amp;lt;/&amp;gt;&quot;
          },
          &quot;leading_diamond&quot;: &quot; \ue0b6&quot;,
          &quot;trailing_diamond&quot;: &quot;\ue0b4&quot;,
          &quot;template&quot;: &quot;\ue235 {{ if .Error }}{{ .Error }}{{ else }}{{ if .Venv }}{{ .Venv }} {{ end }}{{ .Full }}{{ end }}&quot;,
          &quot;foreground&quot;: &quot;#100e23&quot;,
          &quot;background&quot;: &quot;#906cff&quot;,
          &quot;type&quot;: &quot;python&quot;,
          &quot;style&quot;: &quot;diamond&quot;
        },
        {
          &quot;properties&quot;: {
            &quot;cache_duration&quot;: &quot;none&quot;
          },
          &quot;leading_diamond&quot;: &quot; \ue0b6&quot;,
          &quot;trailing_diamond&quot;: &quot;\ue0b4&quot;,
          &quot;template&quot;: &quot; {{ .CurrentDate | date .Format }} &quot;,
          &quot;foreground&quot;: &quot;#ffffff&quot;,
          &quot;background&quot;: &quot;#40c4ff&quot;,
          &quot;type&quot;: &quot;time&quot;,
          &quot;style&quot;: &quot;diamond&quot;,
          &quot;invert_powerline&quot;: true
        }
      ]
    },
    {
      &quot;type&quot;: &quot;prompt&quot;,
      &quot;alignment&quot;: &quot;left&quot;,
      &quot;segments&quot;: [
        {
          &quot;properties&quot;: {
            &quot;cache_duration&quot;: &quot;none&quot;
          },
          &quot;template&quot;: &quot;\u2570\u2500&quot;,
          &quot;foreground&quot;: &quot;#21c7c7&quot;,
          &quot;type&quot;: &quot;text&quot;,
          &quot;style&quot;: &quot;plain&quot;
        },
        {
          &quot;properties&quot;: {
            &quot;always_enabled&quot;: true,
            &quot;cache_duration&quot;: &quot;none&quot;
          },
          &quot;template&quot;: &quot;❯ &quot;,
          &quot;foreground&quot;: &quot;#e0f8ff&quot;,
          &quot;type&quot;: &quot;exit&quot;,
          &quot;style&quot;: &quot;plain&quot;,
          &quot;foreground_templates&quot;: [&quot;{{ if gt .Code 0 }}#ef5350{{ end }}&quot;]
        }
      ],
      &quot;newline&quot;: true
    }
  ],
  &quot;version&quot;: 3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;以下のコマンドでPowerShellプロファイルを作成する&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;new-item -type file -path $profile -force
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;以下のコマンドを入力し作成したプロファイルを編集します&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;notepad $PROFILE
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;以下のコマンドをコピペする&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;. $env:USERPROFILE\.config\powershell\user_profile.ps1
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;Terminalを再起動しデザインが反映されていることを確認する
&lt;img src=&quot;./terminal04.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;5. Terminal Iconsをインストールする&lt;/h1&gt;
&lt;p&gt;Terminal Iconsをインストールすることで不足しているフォルダまたはファイルのアイコンを追加することが出来ます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;以下のコマンドでTerminal Iconsをインストールする&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;Install-Module -Name Terminal-Icons -Repository PSGallery
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;user_profile.ps1&lt;/code&gt;を編集する&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以下のコマンドを追記する&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# set PowerShell to UTF-8
[console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding

# Prompt
$omp_config = Join-Path $PSScriptRoot &quot;.\user.omp.json&quot;
oh-my-posh --init --shell pwsh --config $omp_config | Invoke-Expression

# Terminal Icons
Import-Module -Name Terminal-Icons
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;Terminalを再起動し、&lt;code&gt;ls&lt;/code&gt;コマンドを入力後、アイコンが適用されていることを確認する
&lt;img src=&quot;./terminal05.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;参考にさせていただいたサイト・動画&lt;/h1&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5-aK2_WwrmM?si=8K7wIFxGbdiYxkZx&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allowfullscreen class=&quot;mb-2&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;p&gt;https://learn.microsoft.com/ja-jp/windows/terminal/tutorials/custom-prompt-setup#customize-your-powershell-prompt-with-oh-my-posh&lt;/p&gt;
</content:encoded></item><item><title>ブログページにコメント機能が付けられる「giscus」をNext.jsで使う</title><link>https://www.y-shin.net/posts/giscus-nextjs/</link><guid isPermaLink="true">https://www.y-shin.net/posts/giscus-nextjs/</guid><description>ブログページにコメント機能が付けられる「giscus」をNext.jsで使う</description><pubDate>Fri, 25 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;お久しぶりです。私のブログにはコメントやリアクションを付けられる機能が無いので「giscus」を使ってコメント機能を実装してみました。&lt;/p&gt;
&lt;h1&gt;giscusとは&lt;/h1&gt;
&lt;p&gt;GithubのDiscussion機能を活用したコメントシステムです。Githubアカウントがあればコメントやリアクションができるようになります。&lt;/p&gt;
&lt;p&gt;https://giscus.app&lt;/p&gt;
&lt;h1&gt;giscusの設定&lt;/h1&gt;
&lt;p&gt;Next.jsでの使用方法&lt;/p&gt;
&lt;h2&gt;1. giscus Appのインストール&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;giscusを導入するリポジトリを公開設定(&lt;code&gt;public&lt;/code&gt;)にする。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以下のリンクにアクセスしgiscusをインストールする&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;https://github.com/apps/giscus&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./01.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;対象のユーザを選択する。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./02.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Only select repositories&lt;/code&gt;を選択し、対象のリポジトリを選択し、&lt;code&gt;Install&lt;/code&gt;をクリックする。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./03.png&quot; alt=&quot;img&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Okay, giscus was installed on the @xxxxxx account.&lt;/code&gt; と出てくれば Installは完了。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;2. リポジトリのDiscussions機能を有効化する&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Githubの対象リポジトリに移動する。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Settings&lt;/code&gt;に移動する&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;General &amp;gt; Features &amp;gt; Discussions&lt;/code&gt;のチェックを有効化する&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;3. giscusの設定を生成する&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://giscus.app/jp&quot;&gt;giscus&lt;/a&gt;にアクセスする。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;giscusの設定を生成する&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;パラメータ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;リポジトリ&lt;/td&gt;
&lt;td&gt;コメント機能を追加したいリポジトリ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ページとDiscussions連携設定&lt;/td&gt;
&lt;td&gt;Discussionのタイトルにページのpathnameを利用する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discussionで使用するカテゴリ&lt;/td&gt;
&lt;td&gt;Announcements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;このカテゴリのみを検索します&lt;/td&gt;
&lt;td&gt;有効化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;記事へのリアクションを有効にする&lt;/td&gt;
&lt;td&gt;有効化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;テーマ&lt;/td&gt;
&lt;td&gt;カラースキームに従う&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;Next.jsのスクリプトに適用する&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;@giscus/react&lt;/code&gt;ライブラリを使用しています。&lt;br /&gt;
生成された&lt;code&gt;script&lt;/code&gt;を参考に設定する。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ライブラリをインストールする。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;npm install @giscus/react
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;giscus.jsx&lt;/code&gt;を作成する。&lt;br /&gt;
&lt;code&gt;.env&lt;/code&gt;ファイルにリポジトリ名、リポジトリID、カテゴリ、カテゴリIDを定義している。&lt;br /&gt;
また、Light / Drak Modeに対応させるため、&lt;code&gt;theme&lt;/code&gt;の部分は可変にしている。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;import Giscus from &quot;@giscus/react&quot;;
import { useTheme } from &quot;next-themes&quot;;
import { useEffect, useState } from &quot;react&quot;;

export const Comment = () =&amp;gt; {
  const { theme, systemTheme } = useTheme();
  const [giscusTheme, setGiscusTheme] = useState(&quot;light&quot;);

  useEffect(() =&amp;gt; {
    // themeが&apos;system&apos;の場合は、システムのテーマに基づいてGiscusのテーマを決定
    const resolvedTheme = theme === &quot;system&quot; ? systemTheme : theme;

    // Giscusのテーマを設定
    setGiscusTheme(resolvedTheme === &quot;dark&quot; ? &quot;dark&quot; : &quot;light&quot;);
  }, [theme, systemTheme]);

  return (
    &amp;lt;Giscus
      id=&quot;comments&quot;
      repo={process.env.NEXT_PUBLIC_GISCUS_REPO}
      repoId={process.env.NEXT_PUBLIC_GISCUS_REPO_ID}
      category={process.env.NEXT_PUBLIC_GISCUS_CATEGORY}
      categoryId={process.env.NEXT_PUBLIC_GISCUS_CATEGORY_ID}
      mapping=&quot;pathname&quot;
      reactionsEnabled=&quot;1&quot;
      emitMetadata=&quot;0&quot;
      inputPosition=&quot;bottom&quot;
      theme={giscusTheme} // 動的にテーマを変更
    /&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;page.jsx&lt;/code&gt;に作成したコンポーネントを追加する。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;const Giscus = dynamic(() =&amp;gt; import(&quot;@/app/giscus&quot;).then((m) =&amp;gt; m.Comment), {
  ssr: false,
});

export default function Home() {
  return (
    &amp;lt;main&amp;gt;
      &amp;lt;Giscus /&amp;gt;
    &amp;lt;/main&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;以下のように表示される。
&lt;img src=&quot;./04.png&quot; alt=&quot;img&quot; /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;参考にさせていただいたサイト&lt;/h1&gt;
&lt;p&gt;https://giscus.app&lt;/p&gt;
&lt;p&gt;https://blog.k-bushi.com/post/tech/web/instoducing-giscus-with-hugo-stack/&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;giscus/giscus-component&quot;}&lt;/p&gt;
</content:encoded></item><item><title>個人WEBをNext.js + Chakra UIで書き直しました</title><link>https://www.y-shin.net/posts/rewrite-nextjs/</link><guid isPermaLink="true">https://www.y-shin.net/posts/rewrite-nextjs/</guid><description>あけましておめでとうございます！ HTMLでちょこちょこアップデートしてきた個人WEBサイトを、 勉強も兼ねてNext.jsとChakra UIで書き直しました。</description><pubDate>Sat, 07 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;はじめに&lt;/h1&gt;
&lt;p&gt;あけましておめでとうございます！
HTMLでちょこちょこアップデートしてきた個人WEBサイトを、
勉強も兼ねてNext.jsとChakra UIで書き直しました。
元々JavaScriptやTypeScriptに苦手意識があり、なかなか手を付けられなかったですが、
まあ、年も明けましたし帰省してもクソ暇なので暇つぶしがてら挑戦してみました。&lt;/p&gt;
&lt;h1&gt;microCMS&lt;/h1&gt;
&lt;p&gt;これまでのサイトにブログページを新設しました。
ブログはほかのページよりも更新が多く、ページ自体も増えそうで管理が面倒だなと思っていたところにmicroCMSというAPIベースの日本製のヘッドレスCMSを見つけました。
これを使えばNext.js側は動的なページを1つ作っておくだけでOK。
記事を追加したいときはmicroCMSの管理画面からということで管理も楽で即採用しました。
webhookにも対応しているのもありがたいですね。&lt;/p&gt;
&lt;p&gt;https://microcms.io/&lt;/p&gt;
&lt;h1&gt;Chakra UI&lt;/h1&gt;
&lt;p&gt;React用のUIコンポーネントライブラリです。スタイルがコンポーネント化されていてUIに一貫性を持たせやすくしたライブラリになっています。今までCSSでゴリゴリ書いていたスタイルがタグ指定だけで実現できるのは驚きでした。&lt;/p&gt;
&lt;p&gt;https://chakra-ui.com/&lt;/p&gt;
&lt;h1&gt;Vercel&lt;/h1&gt;
&lt;p&gt;WEBホスティングサービスでは定番らしいです。Githubリポジトリと連携させて変更があれば自動でデプロイが走り常に最新状態のページが表示できるようになります。
自分はmicroCMSのwebhookとも連携させて、記事を追加した際にもデプロイが走るように設定しました。&lt;/p&gt;
&lt;p&gt;https://vercel.com/&lt;/p&gt;
&lt;h1&gt;おわりに&lt;/h1&gt;
&lt;p&gt;まだ、道半ばで使いこなせている感は全くないですが今後も勉強して少しずつサイトをアップデートできたらなと思います。&lt;/p&gt;
&lt;h1&gt;参考にさせて頂いたありがたい記事&lt;/h1&gt;
&lt;p&gt;https://qlitre-weblog.com/next-microcms-blog-w-chakra-matome&lt;/p&gt;
&lt;p&gt;https://blog.microcms.io/microcms-next-jamstack-blog/&lt;/p&gt;
</content:encoded></item></channel></rss>