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 フレームワークが適用されていることを示唆しています。