【Nuxt】Nuxt 3 を要素別に学ぶ：ページ構成・レイアウト・データ取得の基本

# はじめに

Vue.js を使った Web アプリケーション開発において、Nuxt 3 は非常に強力なフレームワークです。サーバーサイドレンダリング（SSR）や静的サイト生成（SSG）、柔軟なルーティングなど、多くの機能を備えており、シンプルな構成でスケーラブルな Web サイトを構築できます。

https://nuxt.com/

この記事では、Nuxt 3 の概要や基本的な使い方を記載します。

# Nuxt 3 とは？

Nuxt 3 は Vue 3 をベースにしたアプリケーションフレームワークで、以下の特徴を持っています。

- Vue 3 Composition API 対応
- SSR（サーバーサイドレンダリング）と SSG（静的サイト生成）対応
- 柔軟なルーティングとファイルベース構成
- `useFetch` や `useAsyncData` などの組み込みユーティリティ
- デフォルトで TypeScript サポート（必要に応じて利用可能）

# 開発環境
開発環境は以下の通りです。

- Windows 11
- VSCode
- Nuxt 3.17.4
- Vue 3.5.14
- Node 22.16.0
- npm 11.4.1

# Nuxt プロジェクトの作成

```powershell
npm create nuxt nuxt-sample
cd nuxt-sample
npm run dev
````

`http://localhost:3000` にアクセスすると、Nuxt 3 のウェルカム画面が表示されます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/13572164-b28e-42d4-b5ef-c471213ae6bf.png)

上記画面は、`app.vue` のコードを表示しています。

```app.vue
<template>
  <div>
    <NuxtRouteAnnouncer />
    <NuxtWelcome />
  </div>
</template>
```

:::note
TypeScript のサポートについて

Nuxt 3 はプロジェクト作成時から TypeScript が有効になっており、設定を変更せずに `.ts` ファイルや `<script setup lang="ts">` を使用できます。
TypeScript を使うかどうかは任意ですが、型情報を活かすことで補完やエラー検出が強化され、開発効率が向上します。
:::

# ディレクトリ構造の概要
Nuxt のプロジェクトには、以下のように自動的に読み込まれる特別なディレクトリがあります。

| ディレクトリ   | 説明                                                  |
| ------------- | ----------------------------------------------------- |
| `pages/`      | ルーティングに対応するページを定義                                     |
| `components/` | UI部品を定義。自動インポートされる                                    |
| `layouts/`    | 各ページで共通して使うレイアウト                                      |
| `app.vue`     | アプリケーション全体のルート |


# ページの作成

Nuxt は Next.js と同じくファイルベースのルーティングです。`pages/` ディレクトリに Vue ファイルを作成すると、自動的にルーティングが設定されます。

https://nuxt.com/docs/guide/directory-structure/pages

なお、`app.vue` を利用する場合、`app.vue` で `<NuxtPage />` を利用する必要があります。
利用しない場合、`pages/` ディレクトリに Vue ファイルを作成するだけで、ルーティング設定ができます。

```app.vue
<template>
  <div>
    <NuxtRouteAnnouncer />
    <NuxtPage />
  </div>
</template>

```

ファイルを作ると、`/about` にアクセスできます。

```pages/about.vue
<template>
  <div>
    <h1>About</h1>
    <p>This is the about page.</p>
  </div>
</template>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/ac335b3e-1733-4ffc-aae1-4f07aeec58ef.png)



# コンポーネントの作成と読み込み

共通パーツ（ヘッダーなど）は `components/` ディレクトリに配置して再利用できます。

https://nuxt.com/docs/guide/directory-structure/components

```components/AppHeader.vue
<template>
  <header>
    <h1>Nuxt Sample</h1>
  </header>
</template>
```

```app.vue
<template>
  <div>
    <NuxtRouteAnnouncer />
    <AppHeader />
    <NuxtPage />
  </div>
</template>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/910057f4-3d34-48a8-916d-bd0be526d2db.png)

:::note
ディレクトリ構成と PascalCase

`components/` 以下にサブディレクトリを作っても、自動的に名前解決されます。

```bash
components/
  └── ui/
        └── Card.vue
```

この場合、コンポーネントは `<UiCard>` として使用できます。

```components/ui/Card.vue
<template>
  <div class="card">
    <slot />
  </div>
</template>

<style scoped>
.card {
  border: 1px solid #ccc;
  border-radius: 8px;
  padding: 1rem;
  background-color: #fff;
}
</style>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/b88441cf-24df-49f4-bd1d-fd949a05e8ed.png)


:::

# レイアウトの作成

共通のレイアウトを定義するには `layouts/` ディレクトリを使用します。

https://nuxt.com/docs/guide/directory-structure/layouts

また、レイアウト機能を正しく機能させるには、ルートの `app.vue` に `<NuxtLayout>` を配置する必要があります。

```app.vue
<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>
```

## デフォルトレイアウト
`layouts/default.vue` は、全ページに適用される「標準レイアウト」です。特にページごとに指定しなければ、このレイアウトが自動的に使われます。

```layouts/default.vue
<template>
  <div>
    <AppHeader />
    <main><slot /></main>
  </div>
</template>
```

このファイルは全ページへ適用されるデフォルトレイアウトになります。

## カスタムレイアウト
特定のページで独自レイアウトを使いたい場合は、新たな `.vue` ファイルを作成します。

```bash
layouts/
  ├── default.vue
  └── blog.vue
```

```layouts/blog.vue
<template>
  <div class="blog-layout">
    <aside>Blog Menu</aside>
    <main><slot /></main>
  </div>
</template>

```

ページ側で `definePageMeta` を使ってレイアウト名を指定すると、カスタムレイアウトを適用できます。

```pages/blog.vue
<script setup>
definePageMeta({
  layout: "blog",
});
</script>

<template>
  <h2>Blog articles</h2>
</template>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/628ecfe3-614a-4ac4-b26a-a9be1f023a4d.png)


# 外部データの取得

Nuxt では `useFetch` を使って簡単に API からデータを取得できます。

https://nuxt.com/docs/api/composables/use-fetch

```pages/posts.vue
<template>
  <div>
    <h1>Posts</h1>
    <ul>
      <li v-for="post in posts" :key="post.id">{{ post.title }}</li>
    </ul>
  </div>
</template>

<script setup>
const { data: posts } = await useFetch('https://jsonplaceholder.typicode.com/posts')
</script>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/58f18ee8-3260-4592-9e56-96ea19869ee6.png)


非同期データの取得もシンプルな記述で実現できます。

# まとめ
Nuxt 3 は Vue 3 をベースにした強力なフレームワークで、SSR や SSG、ファイルベースルーティング、柔軟なレイアウト構成、組み込みのデータ取得機能など、モダンな Web アプリケーション開発を強力にサポートしてくれます。

この記事では、Nuxt プロジェクトの作成からページ・コンポーネント・レイアウトの使い方、外部データの取得方法まで、基本的な流れを一通り紹介しました。

# 参照
* [Nuxt 公式チュートリアル](https://nuxt.com/docs/getting-started/introduction)
* [Nuxt 3 Documentation](https://nuxt.com/docs)