brand logo

ドキュメント

useCookie

useCookieは、SSRに対応したクッキーの読み書きを行うためのコンポーザブルです。

使用方法

ページ、コンポーネント、プラグイン内で、useCookieを使用してSSRに対応した方法でクッキーの読み書きを行うことができます。

const cookie = useCookie(name, options)

useCookieNuxtコンテキストでのみ動作します。

返されるrefはクッキーの値を自動的にJSONにシリアライズおよびデシリアライズします。

Signature
import type { Ref } from 'vue'
import type { CookieParseOptions, CookieSerializeOptions } from 'cookie-es'

export interface CookieOptions<T = any> extends Omit<CookieSerializeOptions & CookieParseOptions, 'decode' | 'encode'> {
  decode?(value: string): T
  encode?(value: T): string
  default?: () => T | Ref<T>
  watch?: boolean | 'shallow'
  readonly?: boolean
}

export interface CookieRef<T> extends Ref<T> {}

export function useCookie<T = string | null | undefined>(
  name: string,
  options?: CookieOptions<T>
): CookieRef<T>

パラメータ

name: クッキーの名前。

options: クッキーの動作を制御するオプション。このオブジェクトには以下のプロパティを含めることができます。

ほとんどのオプションはcookieパッケージに直接渡されます。

プロパティデフォルト説明
decode(value: string) => TdecodeURIComponent + destr.クッキーの値をデコードするカスタム関数。クッキーの値は限られた文字セットを持ち(単純な文字列でなければならない)、この関数を使用して以前にエンコードされたクッキーの値をJavaScriptの文字列や他のオブジェクトにデコードできます。
注意: この関数からエラーがスローされた場合、元のデコードされていないクッキーの値がクッキーの値として返されます。
encode(value: T) => stringJSON.stringify + encodeURIComponentクッキーの値をエンコードするカスタム関数。クッキーの値は限られた文字セットを持ち(単純な文字列でなければならない)、この関数を使用して値をクッキーの値に適した文字列にエンコードできます。
default() => T | Ref<T>undefinedクッキーが存在しない場合にデフォルト値を返す関数。この関数はRefを返すこともできます。
watchboolean | 'shallow'true変更を監視してクッキーを更新するかどうか。trueは深い監視、'shallow'は浅い監視(トップレベルのプロパティのみのデータ変更)、falseは無効化。
注意: クッキーが変更されたときはrefreshCookieuseCookieの値を手動で更新してください。
readonlybooleanfalsetrueの場合、クッキーへの書き込みを無効にします。
maxAgenumberundefinedクッキーの最大年齢(秒単位)、つまりMax-Age Set-Cookie属性の値。指定された数値は切り捨てられて整数に変換されます。デフォルトでは最大年齢は設定されていません。
expiresDateundefinedクッキーの有効期限。デフォルトでは有効期限は設定されていません。ほとんどのクライアントはこれを「非永続的クッキー」と見なし、Webブラウザアプリケーションを終了するなどの条件で削除します。
注意: クッキーストレージモデル仕様では、expiresmaxAgeの両方が設定されている場合、maxAgeが優先されるとされていますが、すべてのクライアントがこれに従うわけではないため、両方が設定されている場合は同じ日時を指すべきです!
expiresmaxAgeのどちらも設定されていない場合、クッキーはセッションのみで、ユーザーがブラウザを閉じたときに削除されます。
httpOnlybooleanfalseHttpOnly属性を設定します。
注意: これをtrueに設定すると、準拠したクライアントはクライアント側のJavaScriptがdocument.cookieでクッキーを見ることを許可しないため、注意が必要です。
securebooleanfalseSecure Set-Cookie属性を設定します。
注意: これをtrueに設定すると、準拠したクライアントはブラウザがHTTPS接続を持たない場合、将来サーバーにクッキーを返送しないため、注意が必要です。これによりハイドレーションエラーが発生する可能性があります。
partitionedbooleanfalsePartitioned Set-Cookie属性を設定します。
注意: これはまだ完全に標準化されていない属性であり、将来的に変更される可能性があります。
これにより、多くのクライアントはこの属性を理解するまで無視する可能性があります。
詳細は提案で確認できます。
domainstringundefinedDomain Set-Cookie属性を設定します。デフォルトではドメインは設定されておらず、ほとんどのクライアントはクッキーを現在のドメインにのみ適用すると見なします。
pathstring'/'Path Set-Cookie属性を設定します。デフォルトでは、パスは"デフォルトパス"と見なされます。
sameSiteboolean | stringundefinedSameSite Set-Cookie属性を設定します。
- trueSameSite属性をStrictに設定し、厳格な同一サイトの強制を行います。
- falseSameSite属性を設定しません。
- 'lax'SameSite属性をLaxに設定し、緩やかな同一サイトの強制を行います。
- 'none'SameSite属性をNoneに設定し、明示的なクロスサイトクッキーを設定します。
- 'strict'SameSite属性をStrictに設定し、厳格な同一サイトの強制を行います。

戻り値

クッキーの値を表すVue Ref<T>を返します。refを更新するとクッキーも更新されます(readonlyが設定されていない限り)。refはSSRに対応しており、クライアントとサーバーの両方で動作します。

基本的な使用法

以下の例では、counterというクッキーを作成します。クッキーが存在しない場合、最初にランダムな値に設定されます。counter変数を更新するたびに、クッキーもそれに応じて更新されます。

app.vue
<script setup lang="ts">
const counter = useCookie('counter')

counter.value = counter.value || Math.round(Math.random() * 1000)
</script>

<template>
  <div>
    <h1>Counter: {{ counter || '-' }}</h1>
    <button @click="counter = null">reset</button>
    <button @click="counter--">-</button>
    <button @click="counter++">+</button>
  </div>
</template>

読み取り専用クッキー

<script setup lang="ts">
const user = useCookie(
  'userInfo',
  {
    default: () => ({ score: -1 }),
    watch: false
  }
)

if (user.value) {
  // 実際の`userInfo`クッキーは更新されません
  user.value.score++
}
</script>

<template>
  <div>User score: {{ user?.score }}</div>
</template>

書き込み可能なクッキー

<script setup lang="ts">
const list = useCookie(
  'list',
  {
    default: () => [],
    watch: 'shallow'
  }
)

function add() {
  list.value?.push(Math.round(Math.random() * 1000))
  // この変更ではlistクッキーは更新されません
}

function save() {
  if (list.value) {
    // 実際の`list`クッキーは更新されます
    list.value = [...list.value]
  }
}
</script>

<template>
  <div>
    <h1>List</h1>
    <pre>{{ list }}</pre>
    <button @click="add">Add</button>
    <button @click="save">Save</button>
  </div>
</template>

APIルートでのクッキー

サーバーAPIルートでクッキーを設定するために、h3パッケージからgetCookiesetCookieを使用できます。

server/api/counter.ts
export default defineEventHandler(event => {
  // カウンタークッキーを読み取る
  let counter = getCookie(event, 'counter') || 0

  // カウンタークッキーを1増やす
  setCookie(event, 'counter', ++counter)

  // JSONレスポンスを送信
  return { counter }
})
サンプルコードの編集とプレビューexamples > advanced > use-cookie

tips

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

はじめに:useCookieで解決できる課題とメリット

NuxtのuseCookieは、サーバーサイドレンダリング(SSR)環境でもクッキーの読み書きをシームレスに行える便利なコンポーザブルです。通常、クッキーはクライアント側のJavaScriptで操作しますが、SSRではサーバーとクライアントの両方で状態を同期させる必要があり、単純なdocument.cookie操作では不十分です。

useCookieを使うことで、サーバーとクライアント間でクッキーの状態を一貫して管理でき、ユーザー認証情報や設定の永続化、トラッキングなどの用途で安全かつ効率的に扱えます。特に、Nuxtのコンテキストに依存して動作するため、SSRの特性を活かした実装が可能です。


まず結論:useCookieのポイントまとめ

  • SSR対応:サーバー・クライアント両方で同じAPIでクッキーを操作可能。
  • リアクティブなrefを返す:値の変更は自動的にクッキーに反映される(readonlyで制御可能)。
  • JSONの自動シリアライズ/デシリアライズ:複雑なオブジェクトも扱いやすい。
  • オプションで細かい制御が可能maxAgehttpOnlyなどの属性設定も柔軟。
  • 変更監視の有無を選択可能:パフォーマンスや用途に応じて監視を制御できる。
  • Nuxtコンテキスト内でのみ動作:プラグインやページ、コンポーネントで利用可能。

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

使うべきケース

  • ユーザーの認証情報やセッション管理
    SSR環境で安全にトークンやユーザー情報を保持したい場合に最適です。

  • ユーザー設定の永続化
    テーマ設定や言語選択など、ユーザーごとの設定をクッキーに保存し、サーバー側でも参照したいとき。

  • サーバーとクライアントで状態を共有したい場合
    SSRで初期レンダリング時にクッキーの値を反映させたいケース。

使わない方がよいケース

  • 極めて機密性の高い情報の保存
    httpOnly属性を付けない限りクライアント側JavaScriptからアクセス可能なため、セキュリティ上のリスクがあります。機密情報はサーバーセッションや安全なストレージを利用しましょう。

  • 大量のデータ保存
    クッキーはサイズ制限(一般的に4KB程度)があるため、大きなデータはローカルストレージやサーバーDBに保存すべきです。

  • クッキーの即時反映が不要な場合
    変更監視を無効にしている場合は、手動で更新処理が必要になるため、単純な読み取り専用の用途に限定したほうが管理しやすいです。


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

1. ユーザーの訪問回数をカウントするクッキー

訪問回数をクッキーに保存し、ページ表示時にカウントアップします。SSR対応なので初回レンダリング時から値を反映可能です。

<script setup lang="ts">
const visitCount = useCookie('visitCount', { default: () => 0 })

// 初期値が0なら1にセット、そうでなければインクリメント
visitCount.value = (visitCount.value ?? 0) + 1
</script>

<template>
  <p>あなたの訪問回数: {{ visitCount }}</p>
</template>

2. ユーザー設定のテーマカラーを保存し、サーバー側でも利用

ユーザーが選択したテーマカラーをクッキーに保存し、SSR時にテーマを反映させます。

<script setup lang="ts">
const theme = useCookie('theme', { default: () => 'light' })

function toggleTheme() {
  theme.value = theme.value === 'light' ? 'dark' : 'light'
}
</script>

<template>
  <button @click="toggleTheme">
    現在のテーマ: {{ theme }}
  </button>
</template>

3. 読み取り専用のユーザー情報クッキー

サーバーからセットされたユーザー情報を読み取り専用で参照し、クライアント側で誤って書き換えないようにします。

<script setup lang="ts">
const userInfo = useCookie('userInfo', { readonly: true })

// userInfo.valueは変更不可。読み取り専用として利用
</script>

<template>
  <div>ユーザー名: {{ userInfo?.name || 'ゲスト' }}</div>
</template>

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

1. SSRとCSRの値の不一致によるHydrationエラー

サーバーでレンダリングしたHTMLとクライアントでの初期状態が異なると、VueのHydrationエラーが発生します。useCookieの初期値はサーバーとクライアントで同じになるように注意しましょう。

特にdefaultオプションで動的な値を返す場合は、サーバーとクライアントで差異が出ないように設計することが重要です。

2. secure属性の設定による挙動の違い

secure: trueを設定すると、HTTPS接続時のみクッキーが送信されます。開発環境でHTTPを使っている場合、クッキーが送信されず、状態が反映されないことがあります。

本番環境でHTTPSを使う場合にのみ設定し、開発時は無効にするなど環境に応じた切り替えが必要です。

3. 変更監視(watch)を無効にした場合の手動更新

watch: falseにすると、refの変更が自動でクッキーに反映されません。クッキーの値を手動で更新したい場合は、refreshCookieなどのユーティリティを使って同期を取る必要があります。

4. HttpOnly属性の制限

httpOnly: trueにするとクライアント側JavaScriptからクッキーが見えなくなります。useCookieはクライアント側でも値を参照できるため、httpOnlyを付けるとクライアント側での読み書きができず、用途が限定されます。


まとめ

NuxtのuseCookieはSSR対応のクッキー管理を簡単に実現し、ユーザー体験の向上や状態管理の効率化に役立ちます。リアクティブなrefで値を扱えるため、Vueのリアクティブシステムと親和性が高いのも特徴です。

ただし、SSRとCSRの整合性やセキュリティ面の注意、環境ごとの設定差異など、実務で使う際には細かな配慮が必要です。本記事のポイントを押さえ、適切に使いこなすことで、Nuxtアプリケーションのクッキー管理をより安全かつ効果的に行えます。


useCookieはNuxtコンテキスト内でのみ動作するため、プラグインやページ、コンポーネントでの利用を推奨します。サーバーAPIルートではgetCookiesetCookieを使い分けましょう。