メインコンテンツへスキップ

reactチュートリアル3(Assets, Metadata, and CSS)

· loading · loading ·
kiitosu
著者
kiitosu
画像処理やデバイスドライバ、データ基盤構築からWebバックエンドまで、多様な領域に携わってきました。地図解析や地図アプリケーションの仕組みにも経験があり、幅広い技術を活かした開発に取り組んでいます。休日は草野球とランニングを楽しんでいます。
目次

NextJSの学習をする。 以下のページを翻訳し記録する。 https://nextjs.org/learn-pages-router/basics/assets-metadata-css

  1. reactチュートリアル1(create a nextjs app)
  2. reactチュートリアル2(Navigate Between Pages)
  3. reactチュートリアル3(Assets, Metadata, and CSS)
  4. reactチュートリアル4(Pre-rendering and Data Fetching)
  5. reactチュートリアル5 (Dynamic Routes)
  6. reactチュートリアル6(API Routes)
  7. reactチュートリアル7(Deploying Your Next.js App)

アセット、メタデータ、CSS | Next.js を学ぶ
#

追加した 2 番目のページには現在スタイルがありません。CSS を追加してページのスタイルを設定しましょう。

Next.js にはCSSSassのサポートが組み込まれています。このコースでは CSS を使用します。

このレッスンでは、Next.js が画像などの静的アセットや<title>タグなどのページ メタデータをどのように処理するかについても説明します

このレッスンで学ぶこと
#

このレッスンでは、次のことを学習します。

  • Next.js に静的ファイル(画像など)を追加する方法。
  • 各ページの内部に表示される内容をカスタマイズする方法。
  • CSS モジュールを使用してスタイル設定された再利用可能な React コンポーネントを作成する方法。
  • グローバル CSS を pages/_app.js に追加する方法。
  • Next.js でのスタイル設定に関する役立つヒント

前提条件
#

CSS の基本的な知識。このコースでは、Next.js アプリに CSS を追加する方法について説明しますが、CSS の基礎については説明しません。Next.js スタイルに関する詳細なドキュメントをお探しの場合は、CSS ドキュメントを参照してください。

Assets
#

Next.js は、画像などの静的アセットを最上位publicディレクトリで提供できます。内部のファイルは、pagesと同様にpublicもアプリケーションのルートから参照できます。publicディレクトリはrobots.txtやGoogleのサイト検証などのその他の静的な資産で役立ちます。より深く学習するためにはStatic File Serving を確認しましょう。

プロファイルピクチャのダウンロード
#

最初に自分のプロファイル写真を手に入れましょう。

  • 自分のプロファイル写真をダウンロードするか、このファイルを使いましょう。
  • public ディレクトリの中にimagesディレクトリを作りましょう。
  • public/imagesにprofile.jpgとして写真を保存しましょう。
  • 写真はおおよそ400px x 400px のサイズが可能です。
  • public ディレクトリの下の使っていないSVGロゴファイルは削除してよいです。

最適化されていない画像
#

通常補HTMLではプロファイル写真を以下のように追加できます。

<img src="/images/profile.jpg" alt="Your Name"/>

しかしこれは以下などのマニュアル作業を必要とします。

  • 異なるスクリーンサイズに対して適応的に表示できること
  • 3rdパーティのツールやライブラリに対して写真を最適化すること
  • 表示画面に入ったときだけ画像をロードすること

Image Componentと画像の最適化
#

next/imageはHTMLの<img>要素の拡張で、モダンウェブ向けの進化です。

Next.jsはデフォルトで画像の最適化をサポートしています。ブラウザがサポートしていればリサイズ、最適化、WebP等の最新のフォーマットの提供ができます。これは小さな画面を持つデバイスに大きな画像を提示してしまうことを避けます。また、これにより新しいイメージフォーマットがブラウザにサポートされるとNextjsは自動的に採用できます。

画像の自動最適化はどのイメージソースにも使うことができます。また、CMS等の外部ソースで提供されている画像も最適化することができます。

Image Componentを使う
#

ビルド時に画像を最適化する代わりに、Next.jsはユーザのリクエストによって要求を受けた時に画像最適化を実施します。静的サイトジェネレータや静的サイトとは違い、画像が10枚だろうが1000万枚だろうがビルド時間は増えません。

画像はデフォルトで遅延読込されます。つまり、画面外の画像がページのスピードの足かせとなることはありません。

画像はCumulative Layout ShiftCore Web Vitalを避けて表示されます。

以下の例でプロフィール写真を表示する例を提示します。heightとwidthは希望する表示サイズで、縦横比はソースイメージと同じです。

Note : このコンポーネントは後で使うので、まだコピーする必要はありません。

import Image from 'next/image';

const YourComponent = () => (
  <Image
    src="/images/profile.jpg" // Route of the image file
    height={144} // Desired size with correct aspect ratio
    width={144} // Desired size with correct aspect ratio
    alt="Your Name"
  />
);

画像の自動最適化についてより深く知るにはドキュメントを確認してください。

Image Componentについて知りたい場合はAPI reference for next/imageを確認してください。

Metadata
#

HTMLタグ等のページのメタデータを変更したい場合はどうでしょうか? <title>は<head>HTMLタグの一部です。Next.jsで<head>タグを変更する方法を詳しく見てみましょう。 <p>pages/index.jsを開き、以下の行を見つけましょう。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p"><</span><span class="nt">Head</span><span class="p">></span> </span></span><span class="line"><span class="cl"> <span class="p"><</span><span class="nt">title</span><span class="p">></span>Create Next App<span class="p"></</span><span class="nt">title</span><span class="p">></span> </span></span><span class="line"><span class="cl"> <span class="p"><</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">"icon"</span> <span class="na">href</span><span class="o">=</span><span class="s">"/favicon.ico"</span><span class="p">/></span> </span></span><span class="line"><span class="cl"><span class="p"></</span><span class="nt">Head</span><span class="p">></span> </span></span></code></pre></div><p>小文字の<head>の代わりに<Head>が使われていることに注意しましょう。 <Head>はNext.jsのビルトインReactコンポーネントです。これによってページのヘッダーを変更することができます。<a href="https://nextjs.org/docs/api-reference/next/head" target="_blank" >next/head</a>からHeadコンポーネントをインポートできます。</p> <h2 class="relative group">first-post.jsにHeadを追加する <div id="first-postjsにheadを追加する" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#first-postjs%e3%81%abhead%e3%82%92%e8%bf%bd%e5%8a%a0%e3%81%99%e3%82%8b" aria-label="アンカー">#</a> </span> </h2> <p>私達はまだ/posts/first-post ルートに<title>を足していませんので、足してみましょう。 pages/posts/first-post.js を開き next/headからのHeadのimportをファイルの先頭に追加しましょう。</p> <p>次に、エクスポートしたFirstPostコンポーネントをHeadコンポーネントをインクルードするように変更しましょう。単にtitleタグを追加します。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">FirstPost</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o"><></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Head</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">title</span><span class="o">></span><span class="nx">First</span> <span class="nx">Post</span><span class="o"><</span><span class="err">/title></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/Head></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="nx">First</span> <span class="nx">Post</span><span class="o"><</span><span class="err">/h1></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">h2</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Link</span> <span class="nx">href</span><span class="o">=</span><span class="s2">"/"</span><span class="o">></span><span class="err">←</span> <span class="nx">Back</span> <span class="nx">to</span> <span class="nx">home</span><span class="o"><</span><span class="err">/Link></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/h2></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/></span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p><a href="http://localhost:3000/posts/first-post" target="_blank" >http://localhost:3000/posts/first-post</a> にアクセスしてみましょう。ブラウザのタブは"First Post"となっているはずです。ブラウザのdeveloper toolsで title tagが <head>に追加していることが確認できます。</p> <p>更にHeadコンポーネントについて学習したい場合は<a href="https://nextjs.org/docs/api-reference/next/head" target="_blank" >API reference for next/head</a>を確認しましょう。</p> <html>タグをカスタマイズしたい場合、例えばlang属性を追加したい場合は pages/_document.js ファイルを作る事で実現できます。[custom Document documentation](https://nextjs.org/docs/advanced-features/custom-document)で更に学習を進めましょう。 <h2 class="relative group"><a href="https://nextjs.org/learn-pages-router/basics/assets-metadata-css/third-party-javascript" target="_blank" >サードパーティjavascript</a> <div id="サードパーティjavascript" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#%e3%82%b5%e3%83%bc%e3%83%89%e3%83%91%e3%83%bc%e3%83%86%e3%82%a3javascript" aria-label="アンカー">#</a> </span> </h2> <p>サードパーティのjavascriptではサードパーティのソースから追加された全てのスクリプトについて言及します。サードパーティのスクリプトは、解析や広告、カスタマーサポートのためのウィジェットなどスクラッチで作る必要のない新しい機能をサイトに追加するために使われます。</p> <h2 class="relative group">サードパーティjavascriptを追加する <div id="サードパーティjavascriptを追加する" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#%e3%82%b5%e3%83%bc%e3%83%89%e3%83%91%e3%83%bc%e3%83%86%e3%82%a3javascript%e3%82%92%e8%bf%bd%e5%8a%a0%e3%81%99%e3%82%8b" aria-label="アンカー">#</a> </span> </h2> <p>Next.jsページにサードパーティのスクリプトを追加する方法を調べましょう。<code>pages/posts/first-post.js</code>を開き、以下の行を探します。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="o"><</span><span class="nx">Head</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">title</span><span class="o">></span><span class="nx">First</span> <span class="nx">Post</span><span class="o"><</span><span class="err">/title></span> </span></span><span class="line"><span class="cl"><span class="o"><</span><span class="err">/Head></span> </span></span></code></pre></div><p>メタデータに加え、できるだけ早くロードと実行が必要なスクリプトは、通常はページの<head>に追加されます。普通のHTML <script> エレメントを使うと、外部スクリプトは次のようにして追加されます。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="o"><</span><span class="nx">Head</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">title</span><span class="o">></span><span class="nx">First</span> <span class="nx">Post</span><span class="o"><</span><span class="err">/title></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">script</span> <span class="nx">src</span><span class="o">=</span><span class="s2">"https://connect.facebook.net/en_US/sdk.js"</span> <span class="o">/></span> </span></span><span class="line"><span class="cl"><span class="o"><</span><span class="err">/Head></span> </span></span></code></pre></div><p>このスクリプトは<a href="https://developers.facebook.com/docs/javascript/quickstart" target="_blank" >Facebook SDK</a>を含み、一般的にFacebookのソーシャルプラグインやその他の機能を導入するために使われます。このやり方で動きますが、このやり方では同じページから収得されたjavascriptコードに関してロードする場合に明確な方法がわかりません。もし、特定のスクリプトがレンダリングをブロックしページコンテンツのロードを遅らせると、パフォーマンスに多大な影響を与えます。</p> <h2 class="relative group">Script Componentを使う <div id="script-componentを使う" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#script-component%e3%82%92%e4%bd%bf%e3%81%86" aria-label="アンカー">#</a> </span> </h2> <p><a href="https://nextjs.org/docs/api-reference/next/script" target="_blank" >next/script</a>はHTMLのscriptエレメントの拡張で追加のスクリプトがフェッチされ実行された時に最適化されます。</p> <p>同じファイルの先頭にnext/scriptからのインポートを追加します。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Script</span> <span class="nx">from</span> <span class="s1">'next/script'</span><span class="p">;</span> </span></span></code></pre></div><p>Script コンポーネントを含めtえ、FirstPostコンポーネントを更新します。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">FirstPost</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o"><></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Head</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">title</span><span class="o">></span><span class="nx">FirstPost</span><span class="o"><</span><span class="err">/title></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/Head></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Script</span> </span></span><span class="line"><span class="cl"> <span class="nx">src</span><span class="o">=</span><span class="s2">"https://connect.facebook.net/en_US/sdk.js"</span> </span></span><span class="line"><span class="cl"> <span class="nx">strategy</span><span class="o">=</span><span class="s2">"lazyOnload"</span> </span></span><span class="line"><span class="cl"> <span class="nx">onLoad</span><span class="o">=</span><span class="p">{()=></span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`script loaded correctly, window.FB has been polypated`</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="o">/></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="nx">First</span> <span class="nx">Post</span><span class="o"><</span><span class="err">/h1></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">h2</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Link</span> <span class="nx">href</span><span class="o">=</span><span class="s2">"/"</span><span class="o">><-</span><span class="nx">Back</span> <span class="nx">to</span> <span class="nx">home</span><span class="o"><</span><span class="err">/Link></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/h2></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/></span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>Scriptコンポーネントに追加の属性があることに注意してください。</p> <ul> <li>strategy はサードパーティスクリプトがいつロードされるべきかをコントロールします。lazyOnloadはNext.jsにこのスクリプトをアイドル時間に読み込むように指示します。</li> <li>onLoadはスクリプトのロードが終了したあと即座にどの様なjavascriptでも実行するために使われます。</li> </ul> <p><a href="http://localhost:3000/posts/first-post" target="_blank" >http://localhost:3000/posts/first-post</a>にアクセスしてみましょう。ブラウザのデベロッパーツールでコンソールパネルで見ることができます。さらに、グローバル変数で生成されたwindow.FBの実行ができます。</p> <p>Note:Facebook SDKはパフォーマンス的な方法でサードパーティスクリプトを追加する方法を説明するためだけに使われています。これでサードパーティ関数をNext.js煮含める方法を理解しました。続ける前にscriptコンポーネントを削除できます。更に学習するには<a href="https://nextjs.org/docs/basic-features/script" target="_blank" >documentation</a>を確認しましょう・</p> <h2 class="relative group"><a href="https://nextjs.org/learn-pages-router/basics/assets-metadata-css/css-styling" target="_blank" >CSS Styling</a> <div id="css-styling" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#css-styling" aria-label="アンカー">#</a> </span> </h2> <p>見たらわかるように我々のページ(<a href="http://localhost:3000" target="_blank" >http://localhost:3000</a>)は既に何らかのスタイルを持っています。ファイル構造をみると、2つのCSSファイルを持つstylesフォルダが見られます。global.cssとHome.module.cssです。もしない場合は以下のコードでプロジェクトをダウンロードできます。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npx create-next-app nextjs-blog --use-npm --example <span class="s2">"https://github.com/vercel/next-learn/tree/main/basics/assets-metadata-css-starter"</span> </span></span></code></pre></div><p><a href="https://nextjs.org/docs/basic-features/built-in-css-support" target="_blank" >CSS modules</a> によって、ユニークなクラス名を自動生成することでコンポーネントレベルでCSSをローカルスコープとすることができます。これによってクラス名の衝突を気にすることなく同名のCSSクラス名を使うことができます。</p> <p>CSSモジュールに加えて、Next.jsアプリケーションを様々な方法でスタイリングできます。</p> <ul> <li>.cssや.scssファイルのインポートを許可するSass</li> <li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss" target="_blank" >Trailwind CSS</a>のような次世代CSS</li> <li><a href="https://github.com/vercel/styled-jsx" target="_blank" >styled-jsx</a>, <a href="https://github.com/vercel/next.js/tree/canary/examples/with-styled-components" target="_blank" >styled-components</a>, <a href="https://github.com/vercel/next.js/tree/canary/examples/with-emotion" target="_blank" >emotion</a> 等のJSライブラリ内のCSS</li> </ul> <p>ここでは、Next.js内で<a href="https://nextjs.org/docs/basic-features/built-in-css-support" target="_blank" >CSS modules</a>と<a href="https://nextjs.org/docs/basic-features/built-in-css-support#sass-support" target="_blank" >Sass</a>を使う方法について説明します。</p> <h2 class="relative group"><a href="https://nextjs.org/learn-pages-router/basics/assets-metadata-css/layout-component" target="_blank" >Layout Component</a> <div id="layout-component" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#layout-component" aria-label="アンカー">#</a> </span> </h2> <p>最初に全てのページで横断的に共有されるLayoutコンポーネントを作りましょう。</p> <ul> <li>componentsと呼ばれるトップレベルディレクトリを作ります</li> <li>componentsに次の内容のlayout.jsファイルを作ります</li> </ul> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">Layout</span><span class="p">({</span><span class="nx">children</span><span class="p">}){</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o"><</span><span class="nx">div</span><span class="o">></span><span class="p">{</span><span class="nx">children</span><span class="p">}</span><span class="o"><</span><span class="err">/div></span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>次に、pages/posts/first-post.js を開きLayoutコンポーネントのインポートを追加し、最も外側のコンポーネントにします。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Head</span> <span class="nx">from</span> <span class="s1">'next/head'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Link</span> <span class="nx">from</span> <span class="s1">'next/link'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Layout</span> <span class="nx">from</span> <span class="s1">'../../components/Layout'</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">FirstPost</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Layout</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Head</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">title</span><span class="o">></span><span class="nx">First</span> <span class="nx">Post</span><span class="o"><</span><span class="err">/title></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/Head></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="nx">First</span> <span class="nx">Post</span><span class="o"><</span><span class="err">/h1></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">h2</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Link</span> <span class="nx">href</span><span class="o">=</span><span class="s2">"/"</span><span class="o">></span><span class="err">←</span> <span class="nx">Back</span> <span class="nx">to</span> <span class="nx">home</span><span class="o"><</span><span class="err">/Link></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/h2></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/Layout></span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h2 class="relative group">CSSを追加する <div id="cssを追加する" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#css%e3%82%92%e8%bf%bd%e5%8a%a0%e3%81%99%e3%82%8b" aria-label="アンカー">#</a> </span> </h2> <p>ではLayout componentにスタイルを追加してみましょう。そのために<a href="https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css" target="_blank" >CSS Module</a>を使います。これによってReactコンポーネントからCSSファイルをインポートできるようになります。</p> <p>components/layout.module.cssファイルを次の内容で作ります。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="p">.</span><span class="nx">container</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">max</span><span class="o">-</span><span class="nx">width</span><span class="o">:</span> <span class="mi">36</span><span class="nx">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">padding</span><span class="o">:</span> <span class="mi">0</span> <span class="mi">1</span> <span class="nx">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nx">margin</span><span class="o">:</span> <span class="mi">3</span><span class="nx">rem</span> <span class="nx">auto</span> <span class="mi">6</span><span class="nx">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p><strong>重要</strong> <a href="https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css" target="_blank" >CSS Module</a>を使うにはCSSファイル名は .module.css で終わる必要があります。</p> <p>components/layout.jsの中でこのコンテナクラスを使うには以下を実施する必要があります</p> <ul> <li>CSSファイルをインポートしstyles等の名前を割り当てます</li> <li>クラス名としてstyles.containerを使います</li> </ul> <p>components/layout.jsを開き内容を以下に書き換えます。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">styles</span> <span class="nx">from</span> <span class="s1">'./layout.module.css'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">Layout</span><span class="p">({</span><span class="nx">children</span><span class="p">}){</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">styles</span><span class="p">.</span><span class="nx">container</span><span class="p">}</span><span class="o">></span><span class="p">{</span><span class="nx">children</span><span class="p">}</span><span class="o"><</span><span class="err">/div></span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p><a href="http://localhost:3000/posts/first-post" target="_blank" >http://localhost:3000/posts/first-post</a>に行くと、 テキストが中央に配置したコンテナの内部にあることがわかります。 <figure> <img class="my-0 rounded-md" loading="lazy" decoding="async" fetchpriority="low" alt="alt text" srcset=" /posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB3assets-metadata-and-css/image_hu_4b8b6e65b55dcef2.jpg 330w, /posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB3assets-metadata-and-css/image_hu_fd261ad019ea5f76.jpg 660w, /posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB3assets-metadata-and-css/image_hu_bf6c0c16d948fd4b.jpg 1280w " data-zoom-src="/posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB3assets-metadata-and-css/image.jpg" src="/posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB3assets-metadata-and-css/image.jpg"> </figure> </p> <h2 class="relative group">ユニーククラス名の自動生成 <div id="ユニーククラス名の自動生成" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#%e3%83%a6%e3%83%8b%e3%83%bc%e3%82%af%e3%82%af%e3%83%a9%e3%82%b9%e5%90%8d%e3%81%ae%e8%87%aa%e5%8b%95%e7%94%9f%e6%88%90" aria-label="アンカー">#</a> </span> </h2> <p>ブラウザのdevtoolsでHTMLを見てみるとLayoutコンポーネントで描画されたdivはlayout_container__…のような名前のクラスを持つことがわかります。 <figure> <img class="my-0 rounded-md" loading="lazy" decoding="async" fetchpriority="low" alt="alt text" srcset=" /posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB3assets-metadata-and-css/image-1_hu_3deccaadfed529a5.jpg 330w, /posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB3assets-metadata-and-css/image-1_hu_bccaf581ce6c9d0.jpg 660w, /posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB3assets-metadata-and-css/image-1_hu_61392f0524d3a2bd.jpg 1280w " data-zoom-src="/posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB3assets-metadata-and-css/image-1.jpg" src="/posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB3assets-metadata-and-css/image-1.jpg"> </figure> </p> <p>これが<a href="https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css" target="_blank" >CSS Modules</a>がすくことです。自動的にユニークなクラス名を作ります。CSS Modulesを使う限りは名前の衝突を気にする必要はありません。</p> <p>更には、Next.jsのコード分割機能がはたらきます。これによりそれぞれのページで最低限の量のCSSがロードされることが保証され、これによってバンドルサイズが小さくなります。</p> <p>CSS Modulesはビルド時にjavascriptのバンドルから抽出され、next.jsによって自動ロードされる、.cssファイルが生成されます。</p> <h2 class="relative group"><a href="https://nextjs.org/learn-pages-router/basics/assets-metadata-css/global-styles" target="_blank" >Global Styles</a> <div id="global-styles" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#global-styles" aria-label="アンカー">#</a> </span> </h2> <p><a href="https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css" target="_blank" >CSS Modules</a> はコンポーネントレベルのスタイルとしては便利です。しかし、全てのページになんらかのCSSをロードすることもできます。</p> <p><a href="https://nextjs.org/docs/basic-features/built-in-css-support#adding-a-global-stylesheet" target="_blank" >global CSS</a>をロードするには、pages/_app.jsファイルを作り、次の内容を記載しましょう。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">App</span><span class="p">({</span><span class="nx">Component</span><span class="p">,</span> <span class="nx">pageProps</span><span class="p">})</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o"><</span><span class="nx">Component</span> <span class="p">{...</span><span class="nx">pageProps</span><span class="p">}</span><span class="o">/></span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>_app.jsのdefault export は全てのページをアプリケーションに包み込むトップレベルのリアクトコンポーネントです。このコンポーネントはページ感を遷移する時に状態を意地するためや、ここで実施するようにglobalスタイルを追加するために使います。<a href="https://nextjs.org/docs/advanced-features/custom-app" target="_blank" >_app.js</a>についてもっと学びましょう。</p> <h2 class="relative group">開発サーバーのリスタート <div id="開発サーバーのリスタート" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#%e9%96%8b%e7%99%ba%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc%e3%81%ae%e3%83%aa%e3%82%b9%e3%82%bf%e3%83%bc%e3%83%88" aria-label="アンカー">#</a> </span> </h2> <p><strong>重要</strong>: pages/_app.jsを追加したら、開発サーバーをリスタートする必要があります。Crtl+cでサーバーを止め、<code>npm run dev</code>でサーバーを開始します。</p> <h2 class="relative group">Global CSSの追加 <div id="global-cssの追加" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#global-css%e3%81%ae%e8%bf%bd%e5%8a%a0" aria-label="アンカー">#</a> </span> </h2> <p>NextjsではグローバルCSSを追加する子ができます。pages/_app.jsからのみインポートでき、他のどこからもインポートできません。</p> <p>global CSSがpages/_app.jsの外でインポートできないのは、global CSSがページのすべての要素に影響するからです。</p> <p>もしhomepageから/posts/first-postに移動したら、homepageのglobal stylesは意図せず/posts/first-postに影響を与えるかもしれません。</p> <p>global CSSはどこにでもどの様な名前でも配置できます。以下の作業をやってみましょう。</p> <ul> <li>トップレベルのstylesディレクトリとglobal.cssファイルを作る</li> <li>styles/global.cssにいかのCSSを追加します。このコードはいくつかのスタイルをリセットし、タグの色を変更します。</li> </ul> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="nt">html</span><span class="o">,</span> </span></span><span class="line"><span class="cl"><span class="nt">body</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">padding</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">margin</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">font-family</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="o">-</span><span class="n">apple-system</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">BlinkMacSystemFont</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">Segoe</span> <span class="n">UI</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">Roboto</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">Oxygen</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">Ubuntu</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">Cantarell</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">Fira</span> <span class="n">Sans</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">Droid</span> <span class="n">Sans</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">Helvetica</span> <span class="n">Neue</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="kc">sans-serif</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">line-height</span><span class="p">:</span> <span class="mf">1.6</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span> <span class="mi">18</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="o">*</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">box-sizing</span><span class="p">:</span> <span class="kc">border-box</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nt">a</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">color</span><span class="p">:</span> <span class="mh">#0070f3</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">text-decoration</span><span class="p">:</span> <span class="kc">none</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nt">a</span><span class="p">:</span><span class="nd">hover</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">text-decoration</span><span class="p">:</span> <span class="kc">underline</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nt">img</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">max-width</span><span class="p">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">display</span><span class="p">:</span> <span class="kc">block</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>最後にCSSファイルをpages/_app.jsからインポートしましょう。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// `pages/_app.js` </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">import</span> <span class="s1">'../styles/global.css'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">App</span><span class="p">({</span> <span class="nx">Component</span><span class="p">,</span> <span class="nx">pageProps</span> <span class="p">})</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o"><</span><span class="nx">Component</span> <span class="p">{...</span><span class="nx">pageProps</span><span class="p">}</span> <span class="o">/></span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>これで、<a href="http://localhost:3000/posts/first-post" target="_blank" >http://localhost:3000/posts/first-post</a>にアクセスすればスタイルが設定されていることが見られます。_app.jsインポートされた全てのスタイルがすべてのページに適応されます。</p> <p> <figure> <img class="my-0 rounded-md" loading="lazy" alt="alt text" src="/images//94b6a8f8f8fb4e/image-2.jpg"> </figure> </p> <p>もし適応されない場合は、開発サーバーを再起動してみましょう。</p> <h2 class="relative group"><a href="https://nextjs.org/learn-pages-router/basics/assets-metadata-css/polishing-layout" target="_blank" >Layoutをより美しく</a> <div id="layoutをより美しく" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#layout%e3%82%92%e3%82%88%e3%82%8a%e7%be%8e%e3%81%97%e3%81%8f" aria-label="アンカー">#</a> </span> </h2> <p>これまでは<a href="https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css" target="_blank" >CSS Modules</a>等のコンセプトを見せるために最小のReactとCSScodeを追加してきました。次の<a href="https://nextjs.org/docs/basic-features/data-fetching" target="_blank" >data fetching</a>に進む前にスタイリングとcodeを美しくしましょう。</p> <h2 class="relative group">components/payout.module.cssを更新する <div id="componentspayoutmodulecssを更新する" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#componentspayoutmodulecss%e3%82%92%e6%9b%b4%e6%96%b0%e3%81%99%e3%82%8b" aria-label="アンカー">#</a> </span> </h2> <p>最初にcomponents/layout.module.cssを開き、次のより洗練されたスタイルに更新しましょう。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">container</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">max-width</span><span class="p">:</span> <span class="mi">36</span><span class="kt">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">padding</span><span class="p">:</span> <span class="mi">0</span> <span class="mi">1</span><span class="kt">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">margin</span><span class="p">:</span> <span class="mi">3</span><span class="kt">rem</span> <span class="kc">auto</span> <span class="mi">6</span><span class="kt">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">header</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">display</span><span class="p">:</span> <span class="kc">flex</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">flex-direction</span><span class="p">:</span> <span class="kc">column</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">align-items</span><span class="p">:</span> <span class="kc">center</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">backToHome</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">margin</span><span class="p">:</span> <span class="mi">3</span><span class="kt">rem</span> <span class="mi">0</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h2 class="relative group">styles/utils.module.cssを作る <div id="stylesutilsmodulecssを作る" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#stylesutilsmodulecss%e3%82%92%e4%bd%9c%e3%82%8b" aria-label="アンカー">#</a> </span> </h2> <p>次にCSSユーティリティのクラスを作りましょう。これは複数のコンポーネントで使い回すことができます。次の無いよ言うのstyles/utils.module.cssファイルを作ります。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">heading2Xl</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span> <span class="mf">2.5</span><span class="kt">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">line-height</span><span class="p">:</span> <span class="mf">1.2</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">font-weight</span><span class="p">:</span> <span class="mi">800</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">letter-spacing</span><span class="p">:</span> <span class="mf">-0.05</span><span class="kt">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">margin</span><span class="p">:</span> <span class="mi">1</span><span class="kt">rem</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">headingXl</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span> <span class="mi">2</span><span class="kt">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">line-height</span><span class="p">:</span> <span class="mf">1.3</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">font-weight</span><span class="p">:</span> <span class="mi">800</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">letter-spacing</span><span class="p">:</span> <span class="mf">-0.05</span><span class="kt">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">margin</span><span class="p">:</span> <span class="mi">1</span><span class="kt">rem</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">headingLg</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span> <span class="mf">1.5</span><span class="kt">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">line-height</span><span class="p">:</span> <span class="mf">1.4</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">margin</span><span class="p">:</span> <span class="mi">1</span><span class="kt">rem</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">headingMd</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">font-size</span><span class="p">:</span> <span class="mf">1.2</span><span class="kt">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">line-height</span><span class="p">:</span> <span class="mf">1.5</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">borderCircle</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">border-radius</span><span class="p">:</span> <span class="mi">9999</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">colorInherit</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">color</span><span class="p">:</span> <span class="kc">inherit</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">padding1px</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">padding-top</span><span class="p">:</span> <span class="mi">1</span><span class="kt">px</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">list</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">list-style</span><span class="p">:</span> <span class="kc">none</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">padding</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">margin</span><span class="p">:</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">listItem</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">margin</span><span class="p">:</span> <span class="mi">0</span> <span class="mi">0</span> <span class="mf">1.25</span><span class="kt">rem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">lightText</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">color</span><span class="p">:</span> <span class="mh">#666</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>これらのユーティリティクラスはアプリケーション横断的に再利用でき、global.cssファイルでも使うことができます。ユーティリティクラスは関数というよりはCSSセレクターを書くアプローチに近いです。更に学ぶにはこちら<a href="https://tailwindcss.com/docs/utility-first" target="_blank" >utility-first CSS</a></p> <p>3つ目にcomponents/layout.jsを開き以下のようにcodeを変更します。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Head</span> <span class="nx">from</span> <span class="s1">'next/head'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Image</span> <span class="nx">from</span> <span class="s1">'next/image'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">styles</span> <span class="nx">from</span> <span class="s1">'./layout.module.css'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">utilStyles</span> <span class="nx">from</span> <span class="s1">'../styles/utils.module.css'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Link</span> <span class="nx">from</span> <span class="s1">'next/link'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">name</span> <span class="o">=</span> <span class="s1">'Your Name'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="kr">const</span> <span class="nx">siteTitle</span> <span class="o">=</span> <span class="s1">'Next.js Sample Website'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">Layout</span><span class="p">({</span> <span class="nx">children</span><span class="p">,</span> <span class="nx">home</span> <span class="p">})</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">styles</span><span class="p">.</span><span class="nx">container</span><span class="p">}</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Head</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">link</span> <span class="nx">rel</span><span class="o">=</span><span class="s2">"icon"</span> <span class="nx">href</span><span class="o">=</span><span class="s2">"/favicon.ico"</span> <span class="o">/></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">meta</span> </span></span><span class="line"><span class="cl"> <span class="nx">name</span><span class="o">=</span><span class="s2">"description"</span> </span></span><span class="line"><span class="cl"> <span class="nx">content</span><span class="o">=</span><span class="s2">"Learn how to build a personal website using Next.js"</span> </span></span><span class="line"><span class="cl"> <span class="o">/></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">meta</span> </span></span><span class="line"><span class="cl"> <span class="nx">property</span><span class="o">=</span><span class="s2">"og:image"</span> </span></span><span class="line"><span class="cl"> <span class="nx">content</span><span class="o">=</span><span class="p">{</span><span class="sb">`https://og-image.vercel.app/</span><span class="si">${</span><span class="nb">encodeURI</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="nx">siteTitle</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span><span class="si">}</span><span class="sb">.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="o">/></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">meta</span> <span class="nx">name</span><span class="o">=</span><span class="s2">"og:title"</span> <span class="nx">content</span><span class="o">=</span><span class="p">{</span><span class="nx">siteTitle</span><span class="p">}</span> <span class="o">/></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">meta</span> <span class="nx">name</span><span class="o">=</span><span class="s2">"twitter:card"</span> <span class="nx">content</span><span class="o">=</span><span class="s2">"summary_large_image"</span> <span class="o">/></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/Head></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">header</span> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">styles</span><span class="p">.</span><span class="nx">header</span><span class="p">}</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="nx">home</span> <span class="o">?</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o"><></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Image</span> </span></span><span class="line"><span class="cl"> <span class="nx">priority</span> </span></span><span class="line"><span class="cl"> <span class="nx">src</span><span class="o">=</span><span class="s2">"/images/profile.jpg"</span> </span></span><span class="line"><span class="cl"> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">utilStyles</span><span class="p">.</span><span class="nx">borderCircle</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">height</span><span class="o">=</span><span class="p">{</span><span class="mi">144</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">width</span><span class="o">=</span><span class="p">{</span><span class="mi">144</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">alt</span><span class="o">=</span><span class="s2">""</span> </span></span><span class="line"><span class="cl"> <span class="o">/></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">h1</span> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">utilStyles</span><span class="p">.</span><span class="nx">heading2Xl</span><span class="p">}</span><span class="o">></span><span class="p">{</span><span class="nx">name</span><span class="p">}</span><span class="o"><</span><span class="err">/h1></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/></span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> <span class="o">:</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o"><></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Link</span> <span class="nx">href</span><span class="o">=</span><span class="s2">"/"</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Image</span> </span></span><span class="line"><span class="cl"> <span class="nx">priority</span> </span></span><span class="line"><span class="cl"> <span class="nx">src</span><span class="o">=</span><span class="s2">"/images/profile.jpg"</span> </span></span><span class="line"><span class="cl"> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">utilStyles</span><span class="p">.</span><span class="nx">borderCircle</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">height</span><span class="o">=</span><span class="p">{</span><span class="mi">108</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">width</span><span class="o">=</span><span class="p">{</span><span class="mi">108</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nx">alt</span><span class="o">=</span><span class="s2">""</span> </span></span><span class="line"><span class="cl"> <span class="o">/></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/Link></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">h2</span> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">utilStyles</span><span class="p">.</span><span class="nx">headingLg</span><span class="p">}</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Link</span> <span class="nx">href</span><span class="o">=</span><span class="s2">"/"</span> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">utilStyles</span><span class="p">.</span><span class="nx">colorInherit</span><span class="p">}</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="nx">name</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/Link></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/h2></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/></span> </span></span><span class="line"><span class="cl"> <span class="p">)}</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/header></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">main</span><span class="o">></span><span class="p">{</span><span class="nx">children</span><span class="p">}</span><span class="o"><</span><span class="err">/main></span> </span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="o">!</span><span class="nx">home</span> <span class="o">&&</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">styles</span><span class="p">.</span><span class="nx">backToHome</span><span class="p">}</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Link</span> <span class="nx">href</span><span class="o">=</span><span class="s2">"/"</span><span class="o">></span><span class="err">←</span> <span class="nx">Back</span> <span class="nx">to</span> <span class="nx">home</span><span class="o"><</span><span class="err">/Link></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/div></span> </span></span><span class="line"><span class="cl"> <span class="p">)}</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/div></span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>ここで新しく導入されたのが</p> <ul> <li>ページコンテンツを説明する<a href="https://en.wikipedia.org/wiki/Meta_element" target="_blank" >meta tags</a>(og:image等)</li> <li>タイトルと画像のサイズを調整するブール型のhome属性</li> <li>homeがfalseの場合の"Back to home"リンク</li> <li><a href="https://nextjs.org/docs/api-reference/next/image#priority" target="_blank" >priority</a>属性でnext/imageで事前ロードされるimages</li> </ul> <h2 class="relative group">pages/index.jsを更新する <div id="pagesindexjsを更新する" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#pagesindexjs%e3%82%92%e6%9b%b4%e6%96%b0%e3%81%99%e3%82%8b" aria-label="アンカー">#</a> </span> </h2> <p>最後にホームページを更新しましょう。 pages/index.jsを開き以下のように更新します。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Head</span> <span class="nx">from</span> <span class="s1">'next/head'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Layout</span><span class="p">,</span> <span class="p">{</span> <span class="nx">siteTitle</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">'../components/layout'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">utilStyles</span> <span class="nx">from</span> <span class="s1">'../styles/utils.module.css'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">Home</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Layout</span> <span class="nx">home</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">Head</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">title</span><span class="o">></span><span class="p">{</span><span class="nx">siteTitle</span><span class="p">}</span><span class="o"><</span><span class="err">/title></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/Head></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">section</span> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">utilStyles</span><span class="p">.</span><span class="nx">headingMd</span><span class="p">}</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">p</span><span class="o">></span><span class="p">[</span><span class="nx">Your</span> <span class="nx">Self</span> <span class="nx">Introduction</span><span class="p">]</span><span class="o"><</span><span class="err">/p></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">p</span><span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="nx">This</span> <span class="nx">is</span> <span class="nx">a</span> <span class="nx">sample</span> <span class="nx">website</span> <span class="o">-</span> <span class="nx">you</span><span class="err">’</span><span class="nx">ll</span> <span class="nx">be</span> <span class="nx">building</span> <span class="nx">a</span> <span class="nx">site</span> <span class="nx">like</span> <span class="k">this</span> <span class="nx">on</span><span class="p">{</span><span class="s1">' '</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">a</span> <span class="nx">href</span><span class="o">=</span><span class="s2">"https://nextjs.org/learn"</span><span class="o">></span><span class="nx">our</span> <span class="nx">Next</span><span class="p">.</span><span class="nx">js</span> <span class="nx">tutorial</span><span class="o"><</span><span class="err">/a>.)</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/p></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/section></span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/Layout></span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>[Your Self Introduction]をあなたの自己紹介で置き換えましょう。 以上です!layout codeは洗練化され、次のデータ取得のレッスンに進む準備ができました。 このレッスンのまとめをする前にNextjsのCSSサポートに関連する便利なテクニックについて次のページで学びましょう。</p> <h2 class="relative group"><a href="https://nextjs.org/learn-pages-router/basics/assets-metadata-css/styling-tips" target="_blank" >Styling Tips</a> <div id="styling-tips" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#styling-tips" aria-label="アンカー">#</a> </span> </h2> <p>いくつかの便利なスタイリングのヒントを紹介します。 続くセクションは読むだけでコードの変更はいりません!</p> <h2 class="relative group">クラスを切り替えるためにclsxライブラリを使う <div id="クラスを切り替えるためにclsxライブラリを使う" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#%e3%82%af%e3%83%a9%e3%82%b9%e3%82%92%e5%88%87%e3%82%8a%e6%9b%bf%e3%81%88%e3%82%8b%e3%81%9f%e3%82%81%e3%81%abclsx%e3%83%a9%e3%82%a4%e3%83%96%e3%83%a9%e3%83%aa%e3%82%92%e4%bd%bf%e3%81%86" aria-label="アンカー">#</a> </span> </h2> <p>clsxはクラス名を簡単に変えることができるシンプルなライブラリです。npm installやyarn add clsxでインストールできます。</p> <p>更に詳細には<a href="https://github.com/lukeed/clsx" target="_blank" >document</a>を参照してください。基本的な使い方は</p> <ul> <li>successかerrorとなるtypeを受け入れるAlertコンポーネントを作ることを考えます。</li> <li>successの場合は文字色を緑とし、errorの場合は赤とします。</li> </ul> <p>CSSモジュール(例えばalert.module.css)を次のように書くことができます。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">.</span><span class="nc">success</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">color</span><span class="p">:</span> <span class="kc">green</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">error</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">color</span><span class="p">:</span> <span class="kc">red</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>そしてclsxは以下のように使います</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">styles</span> <span class="nx">from</span> <span class="s1">'./alert.module.css'</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span><span class="nx">clsx</span><span class="p">}</span> <span class="nx">from</span> <span class="s1">'clsx'</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nx">Alert</span><span class="p">({</span><span class="nx">children</span><span class="p">,</span> <span class="nx">type</span><span class="p">}){</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="nx">div</span> </span></span><span class="line"><span class="cl"> <span class="nx">className</span><span class="o">=</span><span class="p">{</span><span class="nx">clsx</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="p">[</span><span class="nx">styles</span><span class="p">.</span><span class="nx">success</span><span class="p">]</span><span class="o">:</span> <span class="nx">type</span> <span class="o">===</span> <span class="s1">'success'</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">[</span><span class="nx">styles</span><span class="p">.</span><span class="nx">error</span><span class="p">]</span><span class="o">:</span> <span class="nx">type</span> <span class="o">===</span> <span class="s1">'error'</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">})}</span> </span></span><span class="line"><span class="cl"> <span class="o">></span> </span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="nx">children</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="o"><</span><span class="err">/div></span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h2 class="relative group">PostCSSコンフィグのカスタマイズ <div id="postcssコンフィグのカスタマイズ" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#postcss%e3%82%b3%e3%83%b3%e3%83%95%e3%82%a3%e3%82%b0%e3%81%ae%e3%82%ab%e3%82%b9%e3%82%bf%e3%83%9e%e3%82%a4%e3%82%ba" aria-label="アンカー">#</a> </span> </h2> <p>Next.jsは<a href="https://postcss.org/" target="_blank" >PostCSS</a>を使い、設定無しでCSSをコンパイルします。PostCSSの設定をするために<a href="https://nextjs.org/docs/advanced-features/customizing-postcss-config#customizing-plugins" target="_blank" >postcss.config.js</a>という名前のトップレベルファイルを作成します。これは<a href="https://tailwindcss.com/" target="_blank" >Tailwind CSS</a>等のライブラリを使っている場合にとても便利です。</p> <p>以下に<a href="https://tailwindcss.com/" target="_blank" >Tailwind CSS</a>を追加する手順を記載します。まずはパッケージをインストールします。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm install -D tailwindcss autoprefixer postcss </span></span></code></pre></div><p>次にpostcss.config.jsを作ります。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// postcss.config.js </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">plugins</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">tailwindsss</span><span class="o">:</span> <span class="p">{},</span> </span></span><span class="line"><span class="cl"> <span class="nx">autoprefixer</span><span class="o">:</span> <span class="p">{},</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>更にtailwind.config.jsでオプションを設定することで<a href="https://tailwindcss.com/docs/content-configuration" target="_blank" >configuring content sources</a>することをおすすめします。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="c1">// tailwind.config.js </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">content</span><span class="o">:</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="s1">'./pages/**/*.{js,ts,jsx,tsx}'</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">'./components/**/*.{js,ts,jsx,tsx}'</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="c1">// For the best performance and to avoid false positives, </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="c1">// be as specific as possible with your content configuration. </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div><p>PostCSS設定についてさらに学習するには<a href="https://nextjs.org/docs/advanced-features/customizing-postcss-config" target="_blank" >documentation for PostCSS</a>を参照してください。</p> <p>Tailwind CSSを簡単に始めるためには<a href="https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss" target="_blank" >サンプルを参照してください</a>.</p> <h2 class="relative group">Sassを使う <div id="sassを使う" class="anchor"></div> <span class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none"> <a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#sass%e3%82%92%e4%bd%bf%e3%81%86" aria-label="アンカー">#</a> </span> </h2> <p>Next.jsは.scssと.sass拡張子を使うことで、<a href="https://nextjs.org/docs/basic-features/built-in-css-support#sass-support" target="_blank" >Sass</a>をインポートできます。<a href="https://nextjs.org/learn-pages-router/basics/assets-metadata-css/styling-tips#:~:text=level%20Sass%20via-,CSS%20Modules,-and%20the%20.module" target="_blank" >CSS Modules</a>、.module.scssあるいは.module.sass拡張子によって、コンポーネントレベルのSassを使うことができます。</p> <p>Next.jsのビルトインSassサポートを使うには<a href="https://github.com/sass/sass" target="_blank" >sass</a>をインストールすることを忘れないでください。</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npm install -D sass </span></span></code></pre></div><p>以上です! NextjsのビルトインCSSサポート、CSSモジュールについてさらに学習するには<a href="https://nextjs.org/docs/basic-features/built-in-css-support" target="_blank" >CSS Documentation</a>を参照してください。</p> <strong class="block mt-8"> <a target="_blank" class="m-1 rounded bg-neutral-300 p-1.5 text-neutral-700 hover:bg-primary-500 hover:text-neutral dark:bg-neutral-700 dark:text-neutral-300 dark:hover:bg-primary-400 dark:hover:text-neutral-800" href="mailto:kh0412@gmail.com?subject=Reply%20to%20react%e3%83%81%e3%83%a5%e3%83%bc%e3%83%88%e3%83%aa%e3%82%a2%e3%83%ab3%ef%bc%88Assets%2c%20Metadata%2c%20and%20CSS%ef%bc%89"> Reply by Email </a> </strong> </div> <h2 class="mt-8 text-2xl font-extrabold mb-10">関連記事</h2> <section class="w-full grid gap-4 sm:grid-cols-2 md:grid-cols-3"> <div class="group-hover-card group relative min-h-full min-w-full overflow-hidden rounded border border-2 border-neutral-200 shadow-2xl dark:border-neutral-700"> <a href="/posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB7deploying-your-next.js-app/" class="absolute inset-0" aria-label="reactチュートリアル7(Deploying Your Next.js App)"></a> <div class="px-6 py-4"> <div class="group-hover-card-title decoration-primary-500 dark:text-neutral text-xl font-bold text-neutral-800 group-hover:underline group-hover:underline-offset-2"> reactチュートリアル7(Deploying Your Next.js App) </div> <div class="group-hover-cancel text-sm text-neutral-500 dark:text-neutral-400"> <div class="flex flex-row flex-wrap items-center"> <time datetime="2025-05-18T00:00:00+09:00">2025年5月18日</time><span class="px-2 text-primary-500">·</span><span> <span id="views_posts/2025-05-18-reactチュートリアル7(Deploying-Your-Next.js-App)/index.md" class="animate-pulse inline-block text-transparent max-h-3 rounded-full -mt-[2px] align-middle bg-neutral-300 dark:bg-neutral-400" title="views" >loading</span > <span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"> <path fill="currentColor" d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg></span></span> </span> <span class="px-2 text-primary-500">·</span><span> <span id="likes_posts/2025-05-18-reactチュートリアル7(Deploying-Your-Next.js-App)/index.md" class="animate-pulse inline-block text-transparent max-h-3 rounded-full -mt-[2px] align-middle bg-neutral-300 dark:bg-neutral-400" title="likes" >loading</span > <span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg></span></span> </span> </div> <div class="flex flex-row flex-wrap items-center"> <a class="relative mt-[0.5rem] mr-2" href="/categories/tech/" ><span class="flex cursor-pointer"> <span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400"> Tech </span> </span> </a > <a class="relative mt-[0.5rem] mr-2" href="/tags/nextjs/" ><span class="flex cursor-pointer"> <span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400"> Nextjs </span> </span> </a > <a class="relative mt-[0.5rem] mr-2" href="/tags/react/" ><span class="flex cursor-pointer"> <span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400"> React </span> </span> </a > </div> </div> </div> <div class="px-6 pt-4 pb-2"></div> </div> <div class="group-hover-card group relative min-h-full min-w-full overflow-hidden rounded border border-2 border-neutral-200 shadow-2xl dark:border-neutral-700"> <a href="/posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB4pre-rendering-and-data-fetching/" class="absolute inset-0" aria-label="reactチュートリアル4(Pre-rendering and Data Fetching)"></a> <div class="px-6 py-4"> <div class="group-hover-card-title decoration-primary-500 dark:text-neutral text-xl font-bold text-neutral-800 group-hover:underline group-hover:underline-offset-2"> reactチュートリアル4(Pre-rendering and Data Fetching) </div> <div class="group-hover-cancel text-sm text-neutral-500 dark:text-neutral-400"> <div class="flex flex-row flex-wrap items-center"> <time datetime="2025-05-18T00:00:00+09:00">2025年5月18日</time><span class="px-2 text-primary-500">·</span><span> <span id="views_posts/2025-05-18-reactチュートリアル4(Pre-rendering-and-Data-Fetching)/index.md" class="animate-pulse inline-block text-transparent max-h-3 rounded-full -mt-[2px] align-middle bg-neutral-300 dark:bg-neutral-400" title="views" >loading</span > <span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"> <path fill="currentColor" d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg></span></span> </span> <span class="px-2 text-primary-500">·</span><span> <span id="likes_posts/2025-05-18-reactチュートリアル4(Pre-rendering-and-Data-Fetching)/index.md" class="animate-pulse inline-block text-transparent max-h-3 rounded-full -mt-[2px] align-middle bg-neutral-300 dark:bg-neutral-400" title="likes" >loading</span > <span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg></span></span> </span> </div> <div class="flex flex-row flex-wrap items-center"> <a class="relative mt-[0.5rem] mr-2" href="/categories/tech/" ><span class="flex cursor-pointer"> <span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400"> Tech </span> </span> </a > <a class="relative mt-[0.5rem] mr-2" href="/tags/nextjs/" ><span class="flex cursor-pointer"> <span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400"> Nextjs </span> </span> </a > <a class="relative mt-[0.5rem] mr-2" href="/tags/react/" ><span class="flex cursor-pointer"> <span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400"> React </span> </span> </a > </div> </div> </div> <div class="px-6 pt-4 pb-2"></div> </div> <div class="group-hover-card group relative min-h-full min-w-full overflow-hidden rounded border border-2 border-neutral-200 shadow-2xl dark:border-neutral-700"> <a href="/posts/2024-05-24-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB6api-routes/" class="absolute inset-0" aria-label="reactチュートリアル6(API Routes)"></a> <div class="px-6 py-4"> <div class="group-hover-card-title decoration-primary-500 dark:text-neutral text-xl font-bold text-neutral-800 group-hover:underline group-hover:underline-offset-2"> reactチュートリアル6(API Routes) </div> <div class="group-hover-cancel text-sm text-neutral-500 dark:text-neutral-400"> <div class="flex flex-row flex-wrap items-center"> <time datetime="2024-05-24T00:00:00+09:00">2024年5月24日</time><span class="px-2 text-primary-500">·</span><span> <span id="views_posts/2024-05-24-reactチュートリアル6(API-Routes)/index.md" class="animate-pulse inline-block text-transparent max-h-3 rounded-full -mt-[2px] align-middle bg-neutral-300 dark:bg-neutral-400" title="views" >loading</span > <span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"> <path fill="currentColor" d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg></span></span> </span> <span class="px-2 text-primary-500">·</span><span> <span id="likes_posts/2024-05-24-reactチュートリアル6(API-Routes)/index.md" class="animate-pulse inline-block text-transparent max-h-3 rounded-full -mt-[2px] align-middle bg-neutral-300 dark:bg-neutral-400" title="likes" >loading</span > <span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg></span></span> </span> </div> <div class="flex flex-row flex-wrap items-center"> <a class="relative mt-[0.5rem] mr-2" href="/categories/tech/" ><span class="flex cursor-pointer"> <span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400"> Tech </span> </span> </a > <a class="relative mt-[0.5rem] mr-2" href="/tags/nextjs/" ><span class="flex cursor-pointer"> <span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400"> Nextjs </span> </span> </a > <a class="relative mt-[0.5rem] mr-2" href="/tags/react/" ><span class="flex cursor-pointer"> <span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400"> React </span> </span> </a > </div> </div> </div> <div class="px-6 pt-4 pb-2"></div> </div> </section> </div> <script type="text/javascript" src="/js/page.min.54b6f4371722649edbe871e431d8670d670878c22be8f36e229fe53cc9b786fe25a834def5e6de621f7a3e37b72bc8cd73839aa5ed907ed6cbd45cd3e1b0fa20.js" integrity="sha512-VLb0NxciZJ7b6HHkMdhnDWcIeMIr6PNuIp/lPMm3hv4lqDTe9ebeYh96Pje3K8jNc4Oape2QftbL1FzT4bD6IA==" data-oid="views_posts/2025-05-18-reactチュートリアル3(Assets,-Metadata,-and-CSS)/index.md" data-oid-likes="likes_posts/2025-05-18-reactチュートリアル3(Assets,-Metadata,-and-CSS)/index.md"></script> </section> <footer class="pt-8 max-w-prose print:hidden"> <div class="pt-8"> <hr class="border-dotted border-neutral-300 dark:border-neutral-600"> <div class="flex justify-between pt-3"> <span> <a class="flex group mr-3" href="/posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB4pre-rendering-and-data-fetching/"> <span class="mr-3 text-neutral-700 group-hover:text-primary-600 ltr:inline rtl:hidden dark:text-neutral dark:group-hover:text-primary-400" >←</span > <span class="ml-3 text-neutral-700 group-hover:text-primary-600 ltr:hidden rtl:inline dark:text-neutral dark:group-hover:text-primary-400" >→</span > <span class="flex flex-col"> <span class="mt-[0.1rem] leading-6 group-hover:underline group-hover:decoration-primary-500" >reactチュートリアル4(Pre-rendering and Data Fetching)</span > <span class="mt-[0.1rem] text-xs text-neutral-500 dark:text-neutral-400"> <time datetime="2025-05-18T00:00:00+09:00">2025年5月18日</time> </span> </span> </a> </span> <span> <a class="flex text-right group ml-3" href="/posts/2025-05-18-react%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB2navigate-between-pages/"> <span class="flex flex-col"> <span class="mt-[0.1rem] leading-6 group-hover:underline group-hover:decoration-primary-500" >reactチュートリアル2(Navigate Between Pages)</span > <span class="mt-[0.1rem] text-xs text-neutral-500 dark:text-neutral-400"> <time datetime="2025-05-18T00:00:00+09:00">2025年5月18日</time> </span> </span> <span class="ml-3 text-neutral-700 group-hover:text-primary-600 ltr:inline rtl:hidden dark:text-neutral dark:group-hover:text-primary-400" >→</span > <span class="mr-3 text-neutral-700 group-hover:text-primary-600 ltr:hidden rtl:inline dark:text-neutral dark:group-hover:text-primary-400" >←</span > </a> </span> </div> </div> </footer> </article> <div id="top-scroller" class="pointer-events-none absolute top-[110vh] bottom-0 w-12 ltr:right-0 rtl:left-0 z-10"> <a href="#the-top" class="pointer-events-auto sticky top-[calc(100vh-5.5rem)] flex h-12 w-12 mb-16 items-center justify-center rounded-full bg-neutral/50 text-xl text-neutral-700 hover:text-primary-600 dark:bg-neutral-800/50 dark:text-neutral dark:hover:text-primary-400" aria-label="TOPへスクロール" title="TOPへスクロール"> ↑ </a> </div> </main><footer id="site-footer" class="py-10 print:hidden"> <nav class="flex flex-row pb-4 text-base font-medium text-neutral-500 dark:text-neutral-400 "> <ul class="flex list-none flex-col sm:flex-row"> <li class=" flex mb-1 ltr:text-right rtl:text-left sm:mb-0 ltr:sm:mr-7 ltr:sm:last:mr-0 rtl:sm:ml-7 rtl:sm:last:ml-0 "> <a class="decoration-primary-500 hover:underline hover:decoration-2 hover:underline-offset-2 flex items-center" href="/tags/" title="Tags"> Tags </a> </li> <li class=" flex mb-1 ltr:text-right rtl:text-left sm:mb-0 ltr:sm:mr-7 ltr:sm:last:mr-0 rtl:sm:ml-7 rtl:sm:last:ml-0 "> <a class="decoration-primary-500 hover:underline hover:decoration-2 hover:underline-offset-2 flex items-center" href="/categories/" title="Categories"> Categories </a> </li> <li class=" flex mb-1 ltr:text-right rtl:text-left sm:mb-0 ltr:sm:mr-7 ltr:sm:last:mr-0 rtl:sm:ml-7 rtl:sm:last:ml-0 "> <a class="decoration-primary-500 hover:underline hover:decoration-2 hover:underline-offset-2 flex items-center" href="/privacy/" title="プライバシーポリシー"> プライバシーポリシー </a> </li> <li class=" flex mb-1 ltr:text-right rtl:text-left sm:mb-0 ltr:sm:mr-7 ltr:sm:last:mr-0 rtl:sm:ml-7 rtl:sm:last:ml-0 "> <a class="decoration-primary-500 hover:underline hover:decoration-2 hover:underline-offset-2 flex items-center" href="/about/" title="著者情報"> 著者情報 </a> </li> </ul> </nav> <div class="flex items-center justify-between"> <p class="text-sm text-neutral-500 dark:text-neutral-400"> © 2025 kiitosu </p> <p class="text-xs text-neutral-500 dark:text-neutral-400"> <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" href="https://gohugo.io/" target="_blank" rel="noopener noreferrer">Hugo</a> & <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" href="https://blowfish.page/" target="_blank" rel="noopener noreferrer">Blowfish</a> で構築されています </p> </div> <script> mediumZoom(document.querySelectorAll("img:not(.nozoom)"), { margin: 24, background: "rgba(0,0,0,0.5)", scrollOffset: 0, }); </script> <script type="text/javascript" src="/js/process.min.ee03488f19c93c2efb199e2e3014ea5f3cb2ce7d45154adb3399a158cac27ca52831db249ede5bb602700ef87eb02434139de0858af1818ab0fb4182472204a4.js" integrity="sha512-7gNIjxnJPC77GZ4uMBTqXzyyzn1FFUrbM5mhWMrCfKUoMdsknt5btgJwDvh+sCQ0E53ghYrxgYqw+0GCRyIEpA=="></script> <script src="/js/plyr.polyfilled.min.js"></script> <script> document.addEventListener('DOMContentLoaded', function () { if (typeof Plyr === 'undefined') return; const targets = document.querySelectorAll('audio.player, video.player, .player'); console.log('plyr targets:', targets.length); Array.from(targets).map(p => new Plyr(p, { controls: ['play','progress','current-time','mute','volume','download','fullscreen'] })); }); </script> </footer> <div id="search-wrapper" class="invisible fixed inset-0 flex h-screen w-screen cursor-default flex-col bg-neutral-500/50 p-4 backdrop-blur-sm dark:bg-neutral-900/50 sm:p-6 md:p-[10vh] lg:p-[12vh] z-500" data-url="https://my-blog-48o.pages.dev/"> <div id="search-modal" class="flex flex-col w-full max-w-3xl min-h-0 mx-auto border rounded-md shadow-lg top-20 border-neutral-200 bg-neutral dark:border-neutral-700 dark:bg-neutral-800"> <header class="relative z-10 flex items-center justify-between flex-none px-2"> <form class="flex items-center flex-auto min-w-0"> <div class="flex items-center justify-center w-8 h-8 text-neutral-400"> <span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg> </span> </div> <input type="search" id="search-query" class="flex flex-auto h-12 mx-1 bg-transparent appearance-none focus:outline-dotted focus:outline-2 focus:outline-transparent" placeholder="検索" tabindex="0"> </form> <button id="close-search-button" class="flex items-center justify-center w-8 h-8 text-neutral-700 hover:text-primary-600 dark:text-neutral dark:hover:text-primary-400" title="閉じる (Esc)"> <span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z"/></svg> </span> </button> </header> <section class="flex-auto px-2 overflow-auto"> <ul id="search-results"> </ul> </section> </div> </div> </div> </body> <script data-name="BMC-Widget" data-cfasync="false" src="https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js" data-id="suy0n9" data-description="Support me on Buy me a coffee!" data-message="" data-color="#FFDD00" data-position="Right" data-x_margin="18" data-y_margin="18"></script> </html>