You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
4
-
5
-
## Startup
6
-
### Setup
7
-
8
-
Make sure to install the dependencies:
9
-
10
-
```bash
11
-
# npm
12
-
npm install
13
-
14
-
# pnpm
15
-
pnpm install
16
-
17
-
# yarn
18
-
yarn install
19
-
20
-
# bun
21
-
bun install
22
-
```
23
-
24
-
### Development Server
25
-
26
-
Start the development server on `http://localhost:3000`:
27
-
28
-
```bash
29
-
# npm
30
-
npm run dev
31
-
32
-
# pnpm
33
-
pnpm run dev
34
-
35
-
# yarn
36
-
yarn dev
37
-
38
-
# bun
39
-
bun run dev
40
-
```
41
-
42
-
### Production
43
-
44
-
Build the application for production:
45
-
46
-
```bash
47
-
# npm
48
-
npm run build
49
-
50
-
# pnpm
51
-
pnpm run build
52
-
53
-
# yarn
54
-
yarn build
55
-
56
-
# bun
57
-
bun run build
58
-
```
59
-
60
-
Locally preview production build:
61
-
62
-
```bash
63
-
# npm
64
-
npm run preview
65
-
66
-
# pnpm
67
-
pnpm run preview
68
-
69
-
# yarn
70
-
yarn preview
71
-
72
-
# bun
73
-
bun run preview
74
-
```
75
-
76
-
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
77
-
78
3
## Story behind
79
4
80
5
We were developing a listing site using Nuxt 3 and aimed to optimize page load times while maintaining SEO benefits by choosing the right rendering mode for each page. Upon investigating this, we found that documentation was limited, particularly for newer and more complex rendering modes like [ISR](#isr). This scarcity was evident in the lack of specific technical details for functionality and testing. Moreover, various rendering modes are referred to differently across knowledge resources, and there are notable differences in implementation among providers such as Vercel, Netlify, etc. This led us to compile the information into the following article, which offers a clear, conceptual explanation and technical insights on setting up different rendering modes in Nuxt 3.
@@ -92,13 +17,13 @@ The pages differ only in their title that refers to the rendering mode used for
92
17
<template>
93
18
<div>
94
19
<p>{{ pageType }} page</p>
95
-
<pre>{{ new Date().toUTCString() }} </pre>
96
-
<pre>{{ data }}</pre>
20
+
<pre>Time after hydration: {{ new Date().toUTCString() }} </pre>
21
+
<pre>Time in server rendered HTML: {{ data }}</pre>
97
22
<NuxtLink to="/">Home</NuxtLink>
98
23
</div>
99
24
</template>
100
25
<script setup lang="ts">
101
-
const pageType = "SWR ttl"; // value differs based on route
26
+
const pageType = "SPA"; // value differs for each route
102
27
const { data } = await useFetch('/api/hello')
103
28
</script>
104
29
```
@@ -131,9 +56,7 @@ Our [API route](server/api/hello.ts) is as simple as this:
| Time in server rendered HTML | HTML response is blank |
169
-
| Time in API response |Fri, 05 Jan 2024 13:26:58 GMT |
170
-
| Time after hydration |Fri, 05 Jan 2024 13:26:58 GMT |
101
+
| Time in API response |Tue, 16 Jan 2024 09:47:10 GMT |
102
+
| Time after hydration |Tue, 16 Jan 2024 09:47:10 GMT |
171
103
172
104
As we can see in the table, the HTML response is blank, and the "Time after hydration" matches the "Time in API response". This occurs because the API request is made client-side. On subsequent requests or page reloads, the HTML response will always be blank, and the time will change with each request. However, the browser-rendered value and the API response value will consistently be the same.
173
105
@@ -192,9 +124,9 @@ We use the route `/ssr` to illustrate the behaviour of this rendering mode:
| Time in server rendered HTML |Fri, 05 Jan 2024 14:07:54 GMT |
196
-
| Time in API response |Fri, 05 Jan 2024 14:07:54 GMT |
197
-
| Time after hydration |Fri, 05 Jan 2024 14:07:55 GMT |
127
+
| Time in server rendered HTML |Tue, 16 Jan 2024 09:47:45 GMT |
128
+
| Time in API response |Tue, 16 Jan 2024 09:47:45 GMT |
129
+
| Time after hydration |Tue, 16 Jan 2024 09:47:48 GMT |
198
130
199
131
In this case, the "Time after hydration" might slightly differ from the "Time in API response" since the API response is generated beforehand. However, the timestamps will be very close to each other because the HTML generation occurs on demand and is not cached. This behavior will remain consistent across subsequent requests or page reloads.
200
132
@@ -217,9 +149,9 @@ The route `/ssg` demonstrates SSG behavior:
| Time in server rendered HTML |Fri, 05 Jan 2024 12:18:57 GMT |
221
-
| Time in API response |Fri, 05 Jan 2024 12:18:57 GMT |
222
-
| Time after hydration |Fri, 05 Jan 2024 14:23:23 GMT |
152
+
| Time in server rendered HTML |Tue, 16 Jan 2024 10:00:41 GMT |
153
+
| Time in API response |Tue, 16 Jan 2024 10:00:41 GMT |
154
+
| Time after hydration |Tue, 16 Jan 2024 10:09:09 GMT |
223
155
224
156
In the table mentioned above, there is a noticeable time difference between the time after hydration and other timestamps. This is because, in SSG mode, HTML is generated during build time and remains unchanged afterward. This behavior will persist across subsequent requests or page reloads.
225
157
@@ -251,13 +183,13 @@ To observe the behavior of the SWR mode without a TTL set, you can take a look a
251
183
252
184
| Data | Value - first request | Value - second request | Value - third request |
| Time in server rendered HTML |Fri, 05 Jan 2024 15:21:03 GMT |Fri, 05 Jan 2024 15:21:03 GMT |Fri, 05 Jan 2024 15:21:09 GMT |
255
-
| Time in API response |Fri, 05 Jan 2024 15:21:03 GMT |Fri, 05 Jan 2024 15:21:03 GMT |Fri, 05 Jan 2024 15:21:09 GMT |
256
-
| Time after hydration |Fri, 05 Jan 2024 15:21:04 GMT |Fri, 05 Jan 2024 15:21:10 GMT |Fri, 05 Jan 2024 15:21:15 GMT |
186
+
| Time in server rendered HTML |Tue, 16 Jan 2024 09:48:55 GMT |Tue, 16 Jan 2024 09:48:55 GMT |Tue, 16 Jan 2024 09:49:02 GMT |
187
+
| Time in API response |Tue, 16 Jan 2024 09:48:55 GMT |Tue, 16 Jan 2024 09:48:55 GMT |Tue, 16 Jan 2024 09:49:02 GMT |
188
+
| Time after hydration |Tue, 16 Jan 2024 09:48:58 GMT |Tue, 16 Jan 2024 09:49:03 GMT |Tue, 16 Jan 2024 09:49:10 GMT |
257
189
258
190
Let's dissect the above table a bit.
259
191
260
-
In the first column, the behavior is similar to that observed with [SSR](#ssr), as the "Time after hydration" slightly differs from the "Time provided in API response". In the second column, it appears the user waited around 7 seconds before reloading the page. The content is served from the cache, with only the time after hydration changing. However, this action triggers the regeneration of the page in the background due to the change in the API response since the first page load. As a result, a new version of the page is obtained upon the third request. To understand this, compare the "Time after hydration" in the second column with the "Time in server rendered HTML" in the third column. The difference is only about 1 second, indicating that the server's rendering of the third request occurred almost concurrently with the serving of the second request.
192
+
In the first column, the behavior is similar to that observed with [SSR](#ssr), as the "Time after hydration" slightly differs from the "Time provided in API response". In the second column, it appears the user waited around 5 seconds before reloading the page. The content is served from the cache, with only the time after hydration changing. However, this action triggers the regeneration of the page in the background due to the change in the API response since the first page load. As a result, a new version of the page is obtained upon the third request. To understand this, compare the "Time after hydration" in the second column with the "Time in server rendered HTML" in the third column. The difference is only about 1 second, indicating that the server's rendering of the third request occurred almost concurrently with the serving of the second request.
@@ -276,9 +208,9 @@ This rendering mode is set up on `/swr_ttl` route:
276
208
277
209
| Data | Value - first request | Value - second request | Value - first request after TTL of 60 seconds passed | Value - second request after TTL of 60 seconds passed |
| Time in server rendered HTML |Fri, 05 Jan 2024 15:30:16 GMT |Fri, 05 Jan 2024 15:30:16 GMT |Fri, 05 Jan 2024 15:30:16 GMT |Fri, 05 Jan 2024 15:31:21 GMT |
280
-
| Time in API response |Fri, 05 Jan 2024 15:30:16 GMT |Fri, 05 Jan 2024 15:30:16 GMT |Fri, 05 Jan 2024 15:30:16 GMT |Fri, 05 Jan 2024 15:31:21 GMT |
281
-
| Time after hydration |Fri, 05 Jan 2024 15:30:17 GMT |Fri, 05 Jan 2024 15:30:28 GMT |Fri, 05 Jan 2024 15:31:22 GMT |Fri, 05 Jan 2024 15:31:29 GMT |
211
+
| Time in server rendered HTML |Tue, 16 Jan 2024 09:49:52 GMT |Tue, 16 Jan 2024 09:49:52 GMT |Tue, 16 Jan 2024 09:49:52 GMT |Tue, 16 Jan 2024 09:50:58 GMT |
212
+
| Time in API response |Tue, 16 Jan 2024 09:49:52 GMT |Tue, 16 Jan 2024 09:49:52 GMT |Tue, 16 Jan 2024 09:49:52 GMT |Tue, 16 Jan 2024 09:50:58 GMT |
213
+
| Time after hydration |Tue, 16 Jan 2024 09:49:55 GMT |Tue, 16 Jan 2024 09:50:00 GMT |Tue, 16 Jan 2024 09:51:00 GMT |Tue, 16 Jan 2024 09:51:06 GMT |
282
214
283
215
In this scenario, the values of the first request in the `/swr_ttl` route are again similar to those observed in [SSR mode](#ssr), with only the time after hydration differing slightly from the other values. For the second and subsequent requests, until the TTL of 60 seconds expires, the "Time in API response" row retains the same timestamp as the first request. After the TTL expires (as shown in the third column), the time in the API response is still stale. However, in the fourth column, a new timestamp appears in the "Time in API response" row, indicating that the content has been updated post-TTL expiry.
284
216
@@ -310,9 +242,9 @@ This mode is available on the `/isr_no_ttl` route:
310
242
311
243
| Data | Value - first request | Value - second request | Value - third request |
| Time in server rendered HTML |Fri, 05 Jan 2024 14:39:23 GMT |Fri, 05 Jan 2024 14:39:23 GMT |Fri, 05 Jan 2024 14:39:23 GMT |
314
-
| Time in API response |Fri, 05 Jan 2024 14:39:23 GMT |Fri, 05 Jan 2024 14:39:23 GMT |Fri, 05 Jan 2024 14:39:23 GMT |
315
-
| Time after hydration |Fri, 05 Jan 2024 14:39:24 GMT |Fri, 05 Jan 2024 14:39:30 GMT |Fri, 05 Jan 2024 14:39:36 GMT |
245
+
| Time in server rendered HTML |Tue, 16 Jan 2024 09:52:54 GMT |Tue, 16 Jan 2024 09:52:54 GMT |Tue, 16 Jan 2024 09:52:54 GMT |
246
+
| Time in API response |Tue, 16 Jan 2024 09:52:54 GMT |Tue, 16 Jan 2024 09:52:54 GMT |Tue, 16 Jan 2024 09:52:54 GMT |
247
+
| Time after hydration |Tue, 16 Jan 2024 09:52:56 GMT |Tue, 16 Jan 2024 09:53:03 GMT |Tue, 16 Jan 2024 09:53:11 GMT |
316
248
317
249
In the table and screencast provided, it's evident that the value in the "Time in API response" row remains unchanged, even after 60 seconds have elapsed, which is typically the default TTL for Vercel. This observation aligns with the behavior of ISR without TTL in Nuxt 3, where the content is cached permanently.
318
250
@@ -333,9 +265,9 @@ The route `/isr_ttl` demonstrates ISR behaviour without TTL:
333
265
334
266
| Data | Value - first request | Value - second request | Value - first request after TTL of 60 seconds passed | Value - second request after TTL of 60 seconds passed |
| Time in server rendered HTML | Tue, 09 Jan 2024 14:32:19 GMT | Tue, 09 Jan 2024 14:32:19 GMT | Tue, 09 Jan 2024 14:32:19 GMT | Tue, 09 Jan 2024 14:33:19 GMT |
337
-
| Time in API response | Tue, 09 Jan 2024 14:32:19 GMT | Tue, 09 Jan 2024 14:32:19 GMT | Tue, 09 Jan 2024 14:32:19 GMT | Tue, 09 Jan 2024 14:33:19 GMT |
338
-
| Time after hydration | Tue, 09 Jan 2024 14:32:20 GMT | Tue, 09 Jan 2024 14:32:27 GMT | Tue, 09 Jan 2024 14:33:20 GMT | Tue, 09 Jan 2024 14:33:27 GMT |
268
+
| Time in server rendered HTML | Tue, 16 Jan 2024 10:01:21 GMT | Tue, 16 Jan 2024 10:01:21 GMT | Tue, 16 Jan 2024 10:01:21 GMT | Tue, 16 Jan 2024 10:02:24 GMT |
269
+
| Time in API response | Tue, 16 Jan 2024 10:01:21 GMT | Tue, 16 Jan 2024 10:01:21 GMT | Tue, 16 Jan 2024 10:01:21 GMT | Tue, 16 Jan 2024 10:02:24 GMT |
270
+
| Time after hydration | Tue, 16 Jan 2024 10:01:24 GMT | Tue, 16 Jan 2024 10:01:28 GMT | Tue, 16 Jan 2024 10:02:25 GMT | Tue, 16 Jan 2024 10:02:32 GMT |
339
271
340
272
For the first request on the `/isr_ttl` route, the observed values are similar to the [SSR behavior](#ssr) behavior, with only the time after hydration showing a slight difference. During the second and subsequent requests, until the TTL of 60 seconds passes, the "Time in API response" row retains the same timestamp as in the first request. After the TTL expires (as shown in the third column), the time in the API response remains stale. It's only in the fourth column that a new timestamp appears in the "Time in API response" row, indicating an update post-TTL expiry.
0 commit comments