Skip to content

Commit b1b77c8

Browse files
committed
update readme: code parts and timestamps, update gifs
1 parent 1c99f30 commit b1b77c8

File tree

8 files changed

+34
-102
lines changed

8 files changed

+34
-102
lines changed

README.md

Lines changed: 34 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,5 @@
11
# Nuxt 3 Rendering modes
22

3-
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-
783
## Story behind
794

805
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
9217
<template>
9318
<div>
9419
<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>
9722
<NuxtLink to="/">Home</NuxtLink>
9823
</div>
9924
</template>
10025
<script setup lang="ts">
101-
const pageType = "SWR ttl"; // value differs based on route
26+
const pageType = "SPA"; // value differs for each route
10227
const { data } = await useFetch('/api/hello')
10328
</script>
10429
```
@@ -131,9 +56,7 @@ Our [API route](server/api/hello.ts) is as simple as this:
13156

13257
```javascript
13358
export default defineEventHandler((event) => {
134-
return {
135-
hello: "world" + new Date().toUTCString(),
136-
};
59+
return new Date().toUTCString();
13760
});
13861
```
13962

@@ -154,6 +77,15 @@ export default defineNuxtConfig({
15477
});
15578
```
15679

80+
#### Startup
81+
Start the example project with:
82+
```bash
83+
git clone [email protected]:RisingStack/nuxt3-rendering-modes.git
84+
cd nuxt3-rendering-modes
85+
pnpm install
86+
pnpm dev
87+
```
88+
15789
### Technical details and showcase
15890
#### SPA
15991

@@ -166,8 +98,8 @@ We use the route `/spa` to illustrate how this rendering mode works:
16698
| Data | Value |
16799
| ------------------------------- | ----------------------------- |
168100
| 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 |
171103

172104
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.
173105

@@ -192,9 +124,9 @@ We use the route `/ssr` to illustrate the behaviour of this rendering mode:
192124

193125
| Data | Value |
194126
| ------------------------------- | ----------------------------- |
195-
| 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 |
198130

199131
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.
200132

@@ -217,9 +149,9 @@ The route `/ssg` demonstrates SSG behavior:
217149

218150
| Data | Value |
219151
| ------------------------------- | ----------------------------- |
220-
| 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 |
223155

224156
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.
225157

@@ -251,13 +183,13 @@ To observe the behavior of the SWR mode without a TTL set, you can take a look a
251183

252184
| Data | Value - first request | Value - second request | Value - third request |
253185
| ------------------------------- | ----------------------------- | ----------------------------- | ----------------------------- |
254-
| 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 |
257189

258190
Let's dissect the above table a bit.
259191

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.
261193

262194
<img src="readme_assets/swr_no_ttl.gif" width="1200"/>
263195

@@ -276,9 +208,9 @@ This rendering mode is set up on `/swr_ttl` route:
276208

277209
| 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 |
278210
| ------------------------------- | ----------------------------- | ----------------------------- | ---------------------------------------------------- | ---------------------------------------------------- |
279-
| 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 |
282214

283215
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.
284216

@@ -310,9 +242,9 @@ This mode is available on the `/isr_no_ttl` route:
310242

311243
| Data | Value - first request | Value - second request | Value - third request |
312244
| ------------------------------- | ----------------------------- | ----------------------------- | ----------------------------- |
313-
| 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 |
316248

317249
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.
318250

@@ -333,9 +265,9 @@ The route `/isr_ttl` demonstrates ISR behaviour without TTL:
333265

334266
| 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 |
335267
| ------------------------------- | ----------------------------- | ----------------------------- | ---------------------------------------------------- | ---------------------------------------------------- |
336-
| 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 |
339271

340272
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.
341273

readme_assets/isr_no_ttl.gif

-1.73 MB
Loading

readme_assets/isr_ttl.gif

-342 KB
Loading

readme_assets/spa.gif

-13.1 MB
Loading

readme_assets/ssg.gif

-16 MB
Loading

readme_assets/ssr.gif

771 KB
Loading

readme_assets/swr_no_ttl.gif

-17.3 MB
Loading

readme_assets/swr_ttl.gif

-12 MB
Loading

0 commit comments

Comments
 (0)