brand logo

ドキュメント

shared

VueアプリとNitroサーバー間で機能を共有するためにshared/ディレクトリを使用します。

shared/ ディレクトリは、VueアプリとNitroサーバーの両方で使用できるコードを共有することを可能にします。

shared/ ディレクトリはNuxt v3.14+で利用可能です。

shared/ ディレクトリ内のコードは、VueやNitroのコードをインポートすることはできません。

既存プロジェクトでの破壊的変更を防ぐため、Nuxt v3では自動インポートはデフォルトで有効になっていません。

これらの自動インポートされたユーティリティと型を使用するには、まず nuxt.config.tsfuture.compatibilityVersion: 4を設定する必要があります

使用方法

方法1: 名前付きエクスポート

shared/utils/capitalize.ts
export const capitalize = (input: string) => {
  return input[0] ? input[0].toUpperCase() + input.slice(1) : ''
}

方法2: デフォルトエクスポート

shared/utils/capitalize.ts
export default function (input: string) {
  return input[0] ? input[0].toUpperCase() + input.slice(1) : ''
}

これで、Nuxtアプリとserver/ディレクトリで自動インポートされたユーティリティを使用できます。

app.vue
<script setup lang="ts">
const hello = capitalize('hello')
</script>

<template>
  <div>
    {{ hello }}
  </div>
</template>
server/api/hello.get.ts
export default defineEventHandler((event) => {
  return {
    hello: capitalize('hello')
  }
})

ファイルのスキャン方法

shared/utils/shared/types/ ディレクトリ内のファイルのみが自動インポートされます。これらのディレクトリのサブディレクトリ内にネストされたファイルは、imports.dirsnitro.imports.dirs にこれらのディレクトリを追加しない限り、自動インポートされません。

shared/utilsshared/types の自動インポートの動作とスキャン方法は、composables/ および utils/ ディレクトリと同じです。

こちらも参照 guide > directory-structure > composables#how-files-are-scanned
Directory Structure
-| shared/
---| capitalize.ts        # 自動インポートされない
---| formatters
-----| lower.ts           # 自動インポートされない
---| utils/
-----| lower.ts           # 自動インポートされる
-----| formatters
-------| upper.ts         # 自動インポートされない
---| types/
-----| bar.d.ts           # 自動インポートされる

shared/ フォルダ内に作成したその他のファイルは、Nuxtによって自動的に設定される#sharedエイリアスを使用して手動でインポートする必要があります:

// sharedディレクトリ直下のファイルの場合
import capitalize from '#shared/capitalize'

// ネストされたディレクトリ内のファイルの場合
import lower from '#shared/formatters/lower'

// utils内のフォルダにネストされたファイルの場合
import upper from '#shared/utils/formatters/upper'

このエイリアスは、インポートするファイルの場所に関係なく、アプリケーション全体で一貫したインポートを保証します。

こちらも参照 guide > concepts > auto-imports

tips

このセクションは公式ドキュメントの翻訳ではなく、本サイト独自の補足記事です。

Nuxtのsharedディレクトリとは?

Nuxt 3.14以降で利用可能なshared/ディレクトリは、Vueアプリケーション(クライアントサイド)とNitroサーバー(サーバーサイド)間でコードを共有できる仕組みです。これにより、同じユーティリティ関数や型定義を両環境で重複なく使い回せるため、開発効率が大幅に向上します。

従来はクライアント用とサーバー用で別々にコードを管理したり、共通コードを外部パッケージ化する必要がありましたが、shared/ディレクトリを使うことでNuxtプロジェクト内でシームレスに共有可能です。


まず結論:sharedディレクトリのポイント

  • VueアプリとNitroサーバー間でコードを共有できる
    ユーティリティ関数や型定義を一箇所にまとめて管理可能。

  • shared/utilsshared/types 配下のファイルは自動インポート対応
    ただし、サブディレクトリは自動インポートされないため注意。

  • shared/内のコードはVueやNitro固有のAPIを使えない
    純粋なユーティリティや型定義に限定される。

  • 既存プロジェクトでは自動インポートはデフォルト無効
    nuxt.config.tsfuture.compatibilityVersion: 4を設定する必要あり。

  • #sharedエイリアスで手動インポートも可能
    自動インポート対象外のファイルはこのエイリアス経由で読み込む。


いつ使うべきか?使わない方がよいケースは?

使うべきケース

  • クライアントとサーバー両方で同じロジック(例:文字列操作、日付フォーマット、バリデーション関数など)を使いたいとき。
  • 型定義を共通化して型安全を保ちたいとき。
  • コードの重複を避けてメンテナンス性を高めたいとき。

使わない方がよいケース

  • VueのリアクティブAPIやNitroのサーバー専用APIを使うコードはshared/に置けません。
    これらはcomposables/server/など適切なディレクトリに分けましょう。

  • 自動インポートの恩恵を受けたい場合は、shared/utilsshared/types直下にファイルを置く必要があります。
    サブディレクトリに深くネストしたい場合は手動インポートが必要です。


実務でよくあるユースケースとサンプルコード

1. 文字列操作ユーティリティの共有

// shared/utils/capitalize.ts
export const capitalize = (input: string) => {
  return input[0] ? input[0].toUpperCase() + input.slice(1) : ''
}
  • クライアント側で表示用に使う
<script setup lang="ts">
const hello = capitalize('hello')
</script>

<template>
  <div>{{ hello }}</div> <!-- 出力: Hello -->
</template>
  • サーバー側APIでレスポンスに利用
// server/api/greet.get.ts
export default defineEventHandler(() => {
  return { message: capitalize('welcome') }
})

2. 型定義の共通化

// shared/types/user.d.ts
export interface User {
  id: number
  name: string
  email: string
}
  • クライアントとサーバーで同じUser型を使い、型の不整合を防止。

3. 日付フォーマット関数の共有

// shared/utils/formatDate.ts
export function formatDate(date: Date): string {
  return date.toISOString().split('T')[0]
}
  • クライアントのUI表示やサーバーのログ出力で共通利用。

よくある落とし穴・注意点

1. VueやNitro固有APIは使えない

shared/内のコードは純粋なユーティリティや型定義に限定されます。Vueのrefcomputed、NitroのdefineEventHandlerなどは使えません。これらを使うコードはcomposables/server/に分けてください。

2. 自動インポートの範囲に注意

shared/utilsshared/types直下のファイルのみ自動インポートされます。サブディレクトリに置いたファイルは自動インポートされないため、nuxt.config.tsimports.dirsnitro.imports.dirsに追加するか、#sharedエイリアスで手動インポートしてください。

3. 既存プロジェクトでの互換性

Nuxt 3の既存プロジェクトでは自動インポートはデフォルト無効です。nuxt.config.tsfuture.compatibilityVersion: 4を設定しないと自動インポートが使えません。設定を忘れると意図した動作にならず混乱することがあります。

4. SSRとHydrationの観点

shared/のコードはサーバー・クライアント両方で動作するため、状態を持つコードや副作用のある処理は避けましょう。状態管理や副作用はVueのライフサイクルやNitroのAPIハンドラで適切に分離してください。


まとめ

Nuxtのshared/ディレクトリは、VueアプリとNitroサーバー間で純粋なユーティリティ関数や型定義を安全かつ効率的に共有できる強力な仕組みです。これによりコードの重複を減らし、メンテナンス性と型安全性を向上させられます。

ただし、VueやNitro固有のAPIは使えない制約があるため、用途に応じてshared/と他のディレクトリを使い分けることが重要です。自動インポートの範囲や既存プロジェクトでの設定にも注意しながら活用しましょう。

Nuxtプロジェクトのコード共有をスマートに実現したい開発者にとって、shared/はぜひ押さえておきたい機能です。