Skip to content
This repository was archived by the owner on May 1, 2025. It is now read-only.

Commit b8fc224

Browse files
authored
feat: content/2.concepts/5.middleware (#48)
* wip * feat: content/2.concepts/5.middleware
1 parent a7370c3 commit b8fc224

File tree

10 files changed

+164
-1
lines changed

10 files changed

+164
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<template>
2+
<NuxtPage />
3+
</template>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default defineNuxtRouteMiddleware(() => {
2+
console.log('Hello from global middleware!')
3+
})
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script setup lang="ts">
2+
definePageMeta({
3+
middleware: ['hello-foo'],
4+
})
5+
</script>
6+
7+
<template>
8+
<h1>Foo</h1>
9+
<NuxtLink to="/">
10+
/Index
11+
</NuxtLink>
12+
</template>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<template>
2+
<h1>Index</h1>
3+
<NuxtLink to="/foo">
4+
/Foo
5+
</NuxtLink>
6+
</template>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { GuideMeta } from '~/types/guides'
2+
3+
export const meta: GuideMeta = {
4+
startingFile: 'pages/index.vue',
5+
features: {
6+
fileTree: true,
7+
},
8+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<template>
2+
<NuxtPage />
3+
</template>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export default defineNuxtRouteMiddleware((to) => {
2+
// FIXME: import . meta . server が置換されてしまう
3+
if (import.meta.server)
4+
return
5+
6+
const isSignedIn = JSON.parse(localStorage.getItem('isSignedIn') || 'false')
7+
8+
if (!isSignedIn && to.path !== '/') {
9+
return navigateTo('/')
10+
}
11+
else {
12+
return true
13+
}
14+
})
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script setup lang="ts">
2+
definePageMeta({
3+
middleware: ['hello-foo'],
4+
})
5+
</script>
6+
7+
<template>
8+
<h1>Foo</h1>
9+
<NuxtLink to="/">
10+
/Index
11+
</NuxtLink>
12+
</template>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script lang="ts" setup>
2+
function setIsSignedIn() {
3+
window.localStorage.setItem('isSignedIn', JSON.stringify(true))
4+
}
5+
6+
function removeIsSignedIn() {
7+
window.localStorage.removeItem('isSignedIn')
8+
}
9+
</script>
10+
11+
<template>
12+
<h1>Index</h1>
13+
<NuxtLink to="/foo">
14+
/Foo
15+
</NuxtLink>
16+
17+
<div>
18+
<button type="button" @click="setIsSignedIn">
19+
Set isSignedIn
20+
</button>
21+
22+
<button type="button" @click="removeIsSignedIn">
23+
Remove isSignedIn
24+
</button>
25+
</div>
26+
</template>

content/2.concepts/5.middleware/index.md

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,80 @@
22
ogImage: true
33
---
44

5-
# Middleware
5+
# ミドルウェア
6+
7+
Nuxt では、特定のルートにナビゲートする前にコードを実行する為のミドルウェアを提供しています。\
8+
この機能は例えば、認証状態によってページへのアクセスを制限する場合などに便利です。
9+
10+
ミドルウェアにはグローバルミドルウェアとページ単位のミドルウェアの2つの種類があります。
11+
どちらも、`middleware` ディレクトリに実装します。
12+
13+
## グローバルミドルウェア
14+
15+
グローバルミドルウェアは以下のように定義することができます。
16+
17+
```
18+
middleware/
19+
--| hello.global.ts
20+
```
21+
22+
```ts
23+
// middleware/hello.global.ts
24+
export default defineNuxtRouteMiddleware(() => {
25+
console.log('hello')
26+
})
27+
```
28+
29+
## ページ単位のミドルウェア
30+
31+
ページ単位のミドルウェアは以下のように定義することができます。
32+
33+
```
34+
middleware/
35+
--| helloA.ts
36+
```
37+
38+
```ts
39+
// middleware/hello.ts
40+
export default defineNuxtRouteMiddleware(() => {
41+
console.log('helloA')
42+
})
43+
```
44+
45+
```vue
46+
<!-- pages/a.vue -->
47+
<script setup lang="ts">
48+
definePageMeta({
49+
middleware: ['hello'],
50+
})
51+
</script>
52+
53+
<template>
54+
<h1>Hello A</h1>
55+
</template>
56+
```
57+
58+
## ミドルウェアの実行タイミング
59+
60+
これらのミドルウェアは、クライアント上でのナビゲーション時はもちろん、SSR または SSG でのページ生成時にもサーバーサイドで実行されます。\
61+
ミドルウェアでローカルストレージなどのクライアントサイドの API を使用する場合は、クライアントサイドのみで実行されるようにする必要があります。\
62+
`import.meta` を使うことで実行している環境を判定することができます。サーバーサイドでの実行スキップする場合は `import.meta.server` を利用します。
63+
64+
```ts
65+
export default defineNuxtRouteMiddleware((to) => {
66+
// skip middleware on server
67+
if (import.meta.server)
68+
return
69+
70+
// some processing
71+
window.localStorage.setItem('key', 'value')
72+
})
73+
```
74+
75+
## チャレンジ
76+
77+
localStorage の情報を読み取って、特定の値がある場合のみ `/foo` にアクセス可能にするミドルウェアを作成してみましょう。\
78+
今回は例として、`isSignedIn` というキーに `true` が設定されている場合のみ `/foo` にアクセス可能にするミドルウェアを作成します。\
79+
値のセットは `index.vue` から行えるようにボタンを設置してみましょう。
80+
81+
:ButtonShowSolution{.bg-faded.px4.py2.rounded.border.border-base.hover:bg-active.hover:text-primary.hover:border-primary:50}

0 commit comments

Comments
 (0)