Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

konjacbot: sync docs@564794d #297

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:

1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
Expand All @@ -24,15 +24,17 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]

- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]

**Additional context**
Add any other context about the problem here.
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/issue_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ about: Standard issue template for Nextjs-docs-ja
title: ''
labels: ''
assignees: ''

---

#### Description
Expand Down
308 changes: 308 additions & 0 deletions docs/01-app/01-getting-started/02-layouts-and-pages.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
---
title: 'レイアウトとページを作成する方法'
nav_title: 'レイアウトとページ'
description: 'Next.jsアプリケーションでレイアウトとページを作成し、リンクする方法を学びます'
related:
title: 'このページで言及されている機能についてもっと学びましょう'
links:
- app/api-reference/file-conventions/layout
- app/api-reference/file-conventions/page
- app/api-reference/components/link
---

Next.jsは**ファイルシステムに基づくルーティング**を使用しています。これにより、フォルダやファイルを使ってルートを定義できます。このページでは、レイアウトやページの作成方法、およびそれらをリンクする方法を案内します。

## ページを作成する {#creating-a-page}

**ページ**とは、特定のルート上でレンダリングされるUIのことです。ページを作成するには、`app`ディレクトリ内に[`page`ファイル](/docs/app/api-reference/file-conventions/page)を追加し、Reactコンポーネントをデフォルトエクスポートします。たとえば、インデックスページ(`/`)を作成するには:

<Image
alt="page.js 特殊ファイル"
srcLight="/docs/light/page-special-file.png"
srcDark="/docs/dark/page-special-file.png"
width="1600"
height="282"
/>

<Tabs>
<TabItem value="tsx" label="TypeScript">

```tsx title="app/page.tsx" switcher
export default function Page() {
return <h1>Hello Next.js!</h1>
}
```

</TabItem>
<TabItem value="jsx" label="JavaScript">

```jsx title="app/page.js" switcher
export default function Page() {
return <h1>Hello Next.js!</h1>
}
```

</TabItem>
</Tabs>

## レイアウトを作成する {#creating-a-layout}

レイアウトとは、複数のページ間で**共有される**UIです。ナビゲーション時にレイアウトは状態を保持し、対話可能であり、再レンダリングされません。

[`layout`ファイル](/docs/app/api-reference/file-conventions/layout)からReactコンポーネントをデフォルトエクスポートすることで、レイアウトを定義できます。このコンポーネントは、[レイアウト](#nesting-layouts)またはページとなる`children`プロップを受け入れる必要があります。

たとえば、インデックスページを子として受け取るレイアウトを作成するには、`app`ディレクトリ内に`layout`ファイルを追加します:

<Image
alt="layout.js 特殊ファイル"
srcLight="/docs/light/layout-special-file.png"
srcDark="/docs/dark/layout-special-file.png"
width="1600"
height="363"
/>

<Tabs>
<TabItem value="tsx" label="TypeScript">

```tsx title="app/layout.tsx" switcher
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* レイアウトUI */}
{/* ページやネストされたレイアウトをレンダリングしたい場所にchildrenを配置 */}
<main>{children}</main>
</body>
</html>
)
}
```

</TabItem>
<TabItem value="jsx" label="JavaScript">

```jsx title="app/layout.js" switcher
export default function DashboardLayout({ children }) {
return (
<html lang="en">
<body>
{/* レイアウトUI */}
{/* ページやネストされたレイアウトをレンダリングしたい場所にchildrenを配置 */}
<main>{children}</main>
</body>
</html>
)
}
```

</TabItem>
</Tabs>

上記のレイアウトは、`app`ディレクトリのrootに定義されているため、[root レイアウト](/docs/app/api-reference/file-conventions/layout#root-layouts)と呼ばれます。

### Root レイアウト(必須) {#root-layout-required}

root レイアウトは最上位レベルで定義され、すべてのルートをラップします。このレイアウトは**必要**であり、`html`および`body`タグを含める必要があります。

## ネストされたルートを作成する {#creating-a-nested-route}

ネストされたルートは、複数のURLセグメントで構成されるルートです。たとえば、`/blog/[slug]`ルートは3つのセグメントで構成されています:

- `/` (Root セグメント)
- `blog` (セグメント)
- `[slug]` (Leaf セグメント)

Next.jsでは:

- **フォルダ**がURLセグメントにマッピングされるルートセグメントを定義するために使用されます。
- **ファイル**(`page`や`layout`など)は、セグメントに表示されるUIを作成するために使用されます。

ネストされたルートを作成するため、フォルダをネストすることができます。たとえば、`/blog`のルートを追加するには、`app`ディレクトリに`blog`というフォルダを作成します。その後、`/blog`を公開アクセス可能にするために`page`ファイルを追加します:

<Image
alt="blogフォルダとpage.jsファイルを示すファイル階層"
srcLight="/docs/light/blog-nested-route.png"
srcDark="/docs/dark/blog-nested-route.png"
width="1600"
height="525"
/>

<Tabs>
<TabItem value="tsx" label="TypeScript">

```tsx title="app/blog/page.tsx" switcher
import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'

export default async function Page() {
const posts = await getPosts()

return (
<ul>
{posts.map((post) => (
<Post key={post.id} post={post} />
))}
</ul>
)
}
```

</TabItem>
</Tabs>
<Tabs>
<TabItem value="jsx" label="JavaScript">

```jsx title="app/blog/[slug]/page.js" switcher
import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'

export default async function Page() {
const posts = await getPosts()

return (
<ul>
{posts.map((post) => (
<Post key={post.id} post={post} />
))}
</ul>
)
}
```

</TabItem>
</Tabs>

フォルダをネストし続けて、ネストされたルートを作成できます。たとえば、特定のブログ記事のルートを作成するには、`blog`内に新たに`[slug]`フォルダを作成し、`page`ファイルを追加します:

<Image
alt="blogフォルダ内にネストされたslugフォルダとpage.jsファイルを示すファイル階層"
srcLight="/docs/light/blog-post-nested-route.png"
srcDark="/docs/dark/blog-post-nested-route.png"
width="1600"
height="687"
/>

<Tabs>
<TabItem value="tsx" label="TypeScript">

```tsx title="app/blog/[slug]/page.tsx" switcher
function generateStaticParams() {}

export default function Page() {
return <h1>Hello, Blog Post Page!</h1>
}
```

</TabItem>
<TabItem value="jsx" label="JavaScript">

```jsx title="app/blog/[slug]/page.js" switcher
function generateStaticParams() {}

export default function Page() {
return <h1>Hello, Blog Post Page!</h1>
}
```

</TabItem>
</Tabs>

> **Good to know**: フォルダ名を角括弧で囲む(例えば`[slug]`)と、特別な**dynamic route segment**が作成され、データから複数のページを生成するのに使用されます。これはブログ記事、製品ページなどに便利です。[dynamic segments](/docs/app/building-your-application/routing/dynamic-routes)についてもっと学びましょう。

### レイアウトをネストする {#nesting-layouts}

デフォルトでは、フォルダ階層内のレイアウトはネストもされます。つまり、`children`プロップを介して子レイアウトをラップします。特定のルートセグメント(フォルダ)内に`layout`を追加することでレイアウトをネストできます。

たとえば、`/blog`ルートのレイアウトを作成するには、`blog`フォルダ内に新たに`layout`ファイルを追加します。

<Image
alt="rootレイアウトがblogレイアウトをラッピングしているファイル階層"
srcLight="/docs/light/nested-layouts.png"
srcDark="/docs/dark/nested-layouts.png"
width="1600"
height="768"
/>

<Tabs>
<TabItem value="tsx" label="TypeScript">

```tsx title="app/blog/layout.tsx" switcher
export default function BlogLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
```

</TabItem>
<TabItem value="jsx" label="JavaScript">

```jsx title="app/blog/layout.js" switcher
export default function BlogLayout({ children }) {
return <section>{children}</section>
}
```

</TabItem>
</Tabs>

上記の2つのレイアウトを組み合わせると、root レイアウト(`app/layout.js`)がblogレイアウト(`app/blog/layout.js`)をラップし、それがブログ(`app/blog/page.js`)とブログ投稿ページ(`app/blog/[slug]/page.js`)をラップします。

## ページ間をリンクする {#linking-between-pages}

ルート間をナビゲートするために[`<Link>`コンポーネント](/docs/app/api-reference/components/link)を使用できます。`<Link>`は、HTML `<a>`タグを拡張してプリフェッチングとクライアントサイドナビゲーションを提供する、組み込みのNext.jsコンポーネントです。

たとえば、ブログ記事のリストを生成するには、`next/link`から`<Link>`をインポートし、コンポーネントに`href`プロップを渡します:

<Tabs>
<TabItem value="tsx" label="TypeScript">

```tsx title="app/ui/post.tsx" highlight={1,6} switcher
import Link from 'next/link'

export default async function Post({ post }) {
const posts = await getPosts()

return (
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}
```

</TabItem>
<TabItem value="jsx" label="JavaScript">

```jsx title="app/ui/post.js" highlight={1,6} switcher
import Link from 'next/link'

export default async function Post({ post }) {
const posts = await getPosts()

return (
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}
```

</TabItem>
</Tabs>

`<Link>`は、Next.jsアプリケーション内でルート間をナビゲートするための主要で推奨される方法です。ただし、[`useRouter`フック](/docs/app/api-reference/functions/use-router)を使用して、より高度なナビゲーションを行うこともできます。
Loading