layout.tsx
layout.tsx
ファイルは、Next.js の App Router 構造における共通のレイアウトコンポーネントです。すべてのページで共通して使用される要素(例えば、ヘッダーやフッター、スタイルの読み込みなど)をこの layout.tsx
ファイルで定義します。
import './styles/globals.scss'
import { Metadata, Viewport } from 'next'
import { App } from '@/components/App'
import { Toaster } from '@/components/ui/sonner'
import { inter } from '@/constants'
import { cn } from '@/lib/utils'
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1.0,
maximumScale: 1.0,
userScalable: false,
viewportFit: 'cover',
}
export const metadata: Metadata = {
title: 'app title',
description: 'App description',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body
className={cn(
'relative h-[var(--app-height)] overscroll-y-none',
inter.className,
)}
>
<App>{children}</App>
<Toaster />
</body>
</html>
)
}
解析
globals.scss
のインポート:
import './styles/globals.scss'
ここでは、グローバルなスタイルシートである globals.scss
を読み込んでいます。このスタイルはすべてのページで適用されます。
Metadata
とViewport
の設定:
import { Metadata, Viewport } from 'next'
Metadata
は、HTML ドキュメントの <head>
要素に含まれるメタ情報(タイトルや説明など)を定義するために使います。Viewport
は、画面のスケーリングや幅を制御するための設定です。
viewport
:
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1.0,
maximumScale: 1.0,
userScalable: false,
viewportFit: 'cover',
}
これは、モバイルデバイス向けに画面のスケーリングと幅を指定しています。userScalable: false
によって、ユーザーによるズームを無効化しています。
metadata
:
export const metadata: Metadata = {
title: 'app title',
description: 'app description',
}
アプリケーションのタイトルと説明を定義しています。これにより、ブラウザのタブに表示されるタイトルや、検索エンジンによるインデックス化で使用される説明文が設定されます。
RootLayout
コンポーネント:
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body
className={cn(
'relative h-[var(--app-height)] overscroll-y-none',
inter.className,
)}
>
<App>{children}</App>
<Toaster />
</body>
</html>
)
}
このコンポーネントがすべてのページのラッパーとして機能し、HTML の基本構造と共通の UI を提供します。
<html lang="en">
:
ページ全体の言語設定を英語にしています。<body>
:className={cn('relative h-[var(--app-height)] overscroll-y-none', inter.className)}
:cn
はクラスネームを効率的に結合するためのユーティリティ関数です。h-[var(--app-height)]
はカスタムプロパティ(CSS変数)を使って高さを指定しています。overscroll-y-none
は、ページを上下にスクロールした際の慣性効果を無効化するスタイルです。inter.className
は、インポートされたフォント設定(inter
)を適用しています。
<App>{children}</App>
:children
は、各ページのコンテンツがここに挿入されます。App
コンポーネントを使って、すべてのページに共通のコンテナやレイアウトが適用されています。
<Toaster />
:
通知(トースト)メッセージを表示するためのコンポーネントです。Toaster
は通常、短期間で消える通知を表示する UI コンポーネントです。
重要なポイント
- 全体のレイアウト: この
RootLayout
は、すべてのページの上位コンポーネントとして機能します。各ページで表示されるコンテンツはchildren
に挿入され、全体のレイアウトやスタイルはここで統一されています。 - カスタムフォント:
inter
という定数は、恐らく Google Fonts などからインポートされたフォント設定で、全体に適用されています。 - 共通機能:
Toaster
のように、全ページで共通して使うコンポーネントがここで配置されます。
page.tsx
import Link from 'next/link'
export default function App() {
return (
<main className="flex min-h-[100dvh] flex-col items-center justify-between p-24">
<Link href="/top">TOP</Link>
</main>
)
}
この page.tsx
ファイルは、Next.js の App Router 構造を使ったルーティングの一部で、アプリケーションのルート (/
) にアクセスした際に表示されるページです。コードは次のように解釈できます。
解析
Link
コンポーネントの使用:
import Link from 'next/link'
Next.js の Link
コンポーネントを使用して、/top
ページへのリンクを作成しています。このリンクをクリックすると、Next.js のクライアントサイドのルーティング機能を利用してページが移動します。
App
コンポーネント:
export default function App() {
ここでは App
コンポーネントがエクスポートされており、このコンポーネントがルートページのコンテンツを表します。
<main>
タグ内のレイアウト:
<main className="flex min-h-[100dvh] flex-col items-center justify-between p-24">
ここでは、<main>
タグ内で Flexbox を使ってレイアウトを制御しています。クラス名 min-h-[100dvh]
は、ビューポートの高さを 100% に設定し、flex-col
は縦方向に要素を並べるためのスタイルを指定しています。また、items-center
は横方向で要素を中央に揃え、justify-between
は縦方向で要素間のスペースを均等にします。
Link
の実装:
<Link href="/top">TOP</Link>
Next.js の Link
コンポーネントを使って、/top
ページへのリンクを作成しています。クリックすると /top
という新しいページに遷移します。
補足
href="/top"
によって、app/top/page.tsx
というファイルが存在する場合、そのページに遷移します。もしapp/top/page.tsx
が存在しない場合、404 エラーページが表示されるはずです。className
で使用されているスタイルは、おそらく Tailwind CSS などのユーティリティファーストの CSS フレームワークが適用されていることを示唆しています。