Skip to content

Commit b003a13

Browse files
committed
update 04-static-site-generation
1 parent 0f75068 commit b003a13

37 files changed

+117
-82
lines changed

04-frameworks/08-nextjs/04-static-site-generation/README.md

Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ _./package.json_
4242
},
4343
```
4444

45-
Take a look `app/cars/_api/car-list.api.ts`, it's using a env variable.
45+
Take a look `src/pods/car-list/api/car-list.api.ts`, it's using a env variable.
4646

4747
Let's create it:
4848

@@ -77,16 +77,14 @@ junit.xml
7777

7878
Now, we will use this method to load car list on build time:
7979

80-
_./app/cars/page.tsx_
80+
_./src/app/cars/page.tsx_
8181

8282
```diff
8383
- 'use client';
8484
import React from 'react';
8585
- import { useRouter } from 'next/navigation';
8686
+ import { Metadata } from 'next';
87-
+ import { getCarList } from './_api';
88-
+ import { CarList } from './_components';
89-
+ import { mapCarListFromApiToVm } from './car-list.mappers';
87+
+ import { CarList, api, mapCarListFromApiToVm } from '#pods/car-list';
9088

9189
+ export const metadata: Metadata = {
9290
+ title: 'Rent a car - Car list',
@@ -98,7 +96,7 @@ import React from 'react';
9896
- const onNavigateBack = () => {
9997
- router.push('/'); // or router.back()
10098
- };
101-
+ const carList = await getCarList();
99+
+ const carList = await api.getCarList();
102100
+ console.log('Car list at build time:', { carList });
103101

104102
- return (
@@ -120,7 +118,7 @@ export default CarListPage;
120118

121119
Update `layout`:
122120

123-
_./app/cars/layout.tsx_
121+
_./src/app/cars/layout.tsx_
124122

125123
```diff
126124
import React from 'react';
@@ -168,7 +166,7 @@ npm start
168166
>
169167
> [Debugging docs](https://nextjs.org/docs/advanced-features/debugging)
170168
171-
Now, if we want fix the image issue, we needs to create the `BASE_PICTURES_URL` env variable (check `app/cars/car-list.mappers.ts`)
169+
Now, if we want fix the image issue, we needs to create the `BASE_PICTURES_URL` env variable (check `src/pods/car-list/car-list.mappers.ts`)
172170

173171
_./.env.local_
174172

@@ -196,14 +194,12 @@ If we need to define a list of pages to get availables at build time (like each
196194

197195
Update car `page`:
198196

199-
_./app/cars/\[carId\]/page.tsx_
197+
_./src/app/cars/\[carId\]/page.tsx_
200198

201199
```diff
202200
import React from 'react';
203201
import { Metadata } from 'next';
204-
+ import { getCar } from './_api';
205-
+ import { Car } from './_components';
206-
+ import { mapCarFromApiToVm } from './car.mappers';
202+
+ import { Car, api, mapCarFromApiToVm } from '#pods/car';
207203

208204
interface Props {
209205
params: { carId: string };
@@ -219,7 +215,7 @@ export const generateMetadata = async (props: Props): Promise<Metadata> => {
219215
- const CarPage = (props: Props) => {
220216
+ const CarPage = async (props: Props) => {
221217
const { params } = props;
222-
+ const car = await getCar(params.carId);
218+
+ const car = await api.getCar(params.carId);
223219
+ console.log('Car page', car);
224220

225221
- return (
@@ -253,7 +249,7 @@ npm run start:prod
253249
254250
But if we run this code at build time, we need to use [generateStaticParams](https://nextjs.org/docs/app/api-reference/functions/generate-static-params) too:
255251

256-
_./app/cars/\[carId\]/page.tsx_
252+
_./src/app/cars/\[carId\]/page.tsx_
257253

258254
```diff
259255
...
@@ -272,6 +268,21 @@ export const generateMetadata = async (props: Props): Promise<Metadata> => {
272268
...
273269
```
274270

271+
Disable `prefetch`:
272+
273+
_./src/pods/car-list/components/car-item.component.tsx_
274+
275+
```diff
276+
...
277+
return (
278+
<Link
279+
+ prefetch={false}
280+
href={routeConstants.car(car.id)}
281+
className={classes.root}
282+
>
283+
...
284+
```
285+
275286
Run again:
276287

277288
```bash
@@ -286,16 +297,31 @@ npm run start:prod
286297
>
287298
> It will render the HTML for each car detail page.
288299
300+
Enable `prefetch` again:
301+
302+
_./src/pods/car-list/components/car-item.component.tsx_
303+
304+
```diff
305+
...
306+
return (
307+
<Link
308+
- prefetch={false}
309+
href={routeConstants.car(car.id)}
310+
className={classes.root}
311+
>
312+
...
313+
```
314+
289315
We can fix the `page` title on `generateMetadata` using the api method `getCar` to fetch the car name:
290316

291-
_./app/cars/\[carId\]/page.tsx_
317+
_./src/app/cars/\[carId\]/page.tsx_
292318

293319
```diff
294320
...
295321

296322
export const generateMetadata = async (props: Props): Promise<Metadata> => {
297323
const { params } = props;
298-
+ const car = await getCar(params.carId);
324+
+ const car = await api.getCar(params.carId);
299325
return {
300326
- title: `Rent a car - Car ${params.carId} details`,
301327
+ title: `Rent a car - Car ${car.name} details`,
@@ -307,7 +333,7 @@ export const generateMetadata = async (props: Props): Promise<Metadata> => {
307333

308334
> It will fetch the car details data only once.
309335
>
310-
> [Automatic fetch request deduping](https://nextjs.org/docs/app/building-your-application/data-fetching#automatic-fetch-request-deduping)
336+
> [Automatic fetch request deduping](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching#reusing-data-across-multiple-functions)
311337
312338
Run again:
313339

@@ -319,10 +345,10 @@ npm run start:prod
319345

320346
What's if `api-server` has new data, let's use [Incremental Static Regeneration or Revalidating Data](https://nextjs.org/docs/app/building-your-application/data-fetching/revalidating):
321347

322-
_./app/cars/\_api/car-list.api.ts_
348+
_./src/pods/car-list/api/car-list.api.ts_
323349

324350
```diff
325-
import { envConstants } from '@/_core/constants';
351+
import { envConstants } from '#core/constants';
326352
import { Car } from './car-list.api-model';
327353

328354
const url = `${envConstants.BASE_API_URL}/cars`;
@@ -335,23 +361,21 @@ const url = `${envConstants.BASE_API_URL}/cars`;
335361

336362
```
337363

338-
_./app/cars/page.tsx_
364+
_./src/app/cars/page.tsx_
339365

340366
```diff
341367
import React from 'react';
342368
import { Metadata } from 'next';
343-
import { getCarList } from './_api';
344-
import { CarList } from './_components';
345-
import { mapCarListFromApiToVm } from './car-list.mappers';
369+
import { CarList, api, mapCarListFromApiToVm } from '#pods/car-list';
346370

347371
export const metadata: Metadata = {
348372
title: 'Rent a car - Car list',
349373
};
350374

351375
const CarListPage = async () => {
352-
- const carList = await getCarList();
376+
- const carList = await api.getCarList();
353377
+ // cache: 'force-cache' is the default value
354-
+ const carList = await getCarList({ next: { revalidate: 10 } }); // In seconds
378+
+ const carList = await api.getCarList({ next: { revalidate: 10 } }); // In seconds
355379
console.log('Car list at build time:', { carList });
356380

357381
return <CarList carList={mapCarListFromApiToVm(carList)} />;
@@ -361,7 +385,7 @@ export default CarListPage;
361385

362386
```
363387

364-
> It also have [on-demand revalidation](https://nextjs.org/docs/app/building-your-application/data-fetching/revalidating#using-on-demand-revalidation)
388+
> It also have other [on-demand revalidation](https://nextjs.org/docs/app/building-your-application/data-fetching/incremental-static-regeneration#time-based-revalidation) options
365389
366390
Run again:
367391

@@ -373,17 +397,17 @@ npm run start:prod
373397

374398
Open browser at `http://localhost:8080/cars` and then add a new car:
375399

376-
_./api-server/mock-data/data.json_
400+
_./api-server/src/mock-data.ts_
377401

378402
```diff
379403
...
380-
+ {
381-
+ "id": "10",
382-
+ "name": "New car",
383-
+ "imageUrl": "/audi-q8.png",
384-
+ "features": [],
385-
+ "isBooked": false
386-
+ }
404+
+ {
405+
+ id: '10',
406+
+ name: 'New car',
407+
+ imageUrl: '/audi-q8.png',
408+
+ features: [],
409+
+ isBooked: false,
410+
+ },
387411
```
388412

389413
While we navigate to car details:(`/cars/1`, `/cars/2`,...`/cars/4`) it doesn't update the car list.
@@ -394,17 +418,17 @@ If we refresh the `/cars` page again (F5) it pre-renders the `car page again` an
394418
395419
Remove data:
396420

397-
_./api-server/mock-data/data.json_
421+
_./api-server/src/mock-data.ts_
398422

399423
```diff
400424
...
401-
- {
402-
- "id": "10",
403-
- "name": "New car",
404-
- "imageUrl": "/vw-touran.png",
405-
- "features": [],
406-
- "isBooked": false
407-
- }
425+
- {
426+
- id: '10',
427+
- name: 'New car',
428+
- imageUrl: '/audi-q8.png',
429+
- features: [],
430+
- isBooked: false,
431+
- },
408432
```
409433

410434
For fix `images` on car details, we nee to add a `domain` to 'optimize images with `next/image` hosted in external service:

04-frameworks/08-nextjs/04-static-site-generation/app/cars/[carId]/_components/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

04-frameworks/08-nextjs/04-static-site-generation/app/cars/_components/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

04-frameworks/08-nextjs/04-static-site-generation/next-env.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
/// <reference types="next/image-types/global" />
33

44
// NOTE: This file should not be edited
5-
// see https://nextjs.org/docs/basic-features/typescript for more information.
5+
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.

04-frameworks/08-nextjs/04-static-site-generation/package.json

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,37 @@
33
"version": "1.0.0",
44
"description": "Nextjs examples",
55
"scripts": {
6-
"start": "run-p -l start:dev start:api-server",
6+
"start": "run-p start:dev start:api-server",
77
"start:dev": "next dev",
88
"build": "rimraf .next && next build",
99
"start:prod": "next start -p 8080",
1010
"start:api-server": "cd api-server && npm run mock-server",
1111
"postinstall": "cd ./api-server && npm install"
1212
},
13+
"imports": {
14+
"#*": [
15+
"./src/*",
16+
"./src/*.ts",
17+
"./src/*.tsx",
18+
"./src/*/index.ts",
19+
"./src/*/index.tsx"
20+
]
21+
},
1322
"author": "Lemoncode",
1423
"license": "MIT",
1524
"dependencies": {
16-
"next": "^14.1.0",
25+
"next": "^14.2.9",
1726
"normalize.css": "^8.0.1",
18-
"react": "^18.2.0",
19-
"react-dom": "^18.2.0",
20-
"sharp": "^0.33.2"
27+
"react": "^18.3.1",
28+
"react-dom": "^18.3.1",
29+
"sharp": "^0.33.5"
2130
},
2231
"devDependencies": {
23-
"@types/node": "20.11.16",
24-
"@types/react": "^18.2.55",
25-
"@types/react-dom": "^18.2.19",
32+
"@types/node": "22.5.4",
33+
"@types/react": "^18.3.5",
34+
"@types/react-dom": "^18.3.0",
2635
"npm-run-all": "^4.1.5",
27-
"rimraf": "^5.0.5",
28-
"typescript": "^5.3.3"
36+
"rimraf": "^6.0.1",
37+
"typescript": "^5.6.2"
2938
}
3039
}

04-frameworks/08-nextjs/04-static-site-generation/app/cars/[carId]/page.tsx renamed to 04-frameworks/08-nextjs/04-static-site-generation/src/app/cars/[carId]/page.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import React from 'react';
22
import { Metadata } from 'next';
3-
import { getCar } from './_api';
4-
import { Car } from './_components';
5-
import { mapCarFromApiToVm } from './car.mappers';
3+
import { Car, api, mapCarFromApiToVm } from '#pods/car';
64

75
interface Props {
86
params: { carId: string };
97
}
108

119
export const generateMetadata = async (props: Props): Promise<Metadata> => {
1210
const { params } = props;
13-
const car = await getCar(params.carId);
11+
const car = await api.getCar(params.carId);
12+
1413
return {
1514
title: `Rent a car - Car ${car.name} details`,
1615
};
@@ -22,7 +21,7 @@ export async function generateStaticParams() {
2221

2322
const CarPage = async (props: Props) => {
2423
const { params } = props;
25-
const car = await getCar(params.carId);
24+
const car = await api.getCar(params.carId);
2625
console.log('Car page', car);
2726

2827
return <Car car={mapCarFromApiToVm(car)} />;

04-frameworks/08-nextjs/04-static-site-generation/app/cars/page.tsx renamed to 04-frameworks/08-nextjs/04-static-site-generation/src/app/cars/page.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import React from 'react';
22
import { Metadata } from 'next';
3-
import { getCarList } from './_api';
4-
import { CarList } from './_components';
5-
import { mapCarListFromApiToVm } from './car-list.mappers';
3+
import { CarList, api, mapCarListFromApiToVm } from '#pods/car-list';
64

75
export const metadata: Metadata = {
86
title: 'Rent a car - Car list',
97
};
108

119
const CarListPage = async () => {
1210
// cache: 'force-cache' is the default value
13-
const carList = await getCarList({ next: { revalidate: 10 } }); // In seconds
11+
const carList = await api.getCarList({ next: { revalidate: 10 } }); // In seconds
1412
console.log('Car list at build time:', { carList });
1513

1614
return <CarList carList={mapCarListFromApiToVm(carList)} />;

0 commit comments

Comments
 (0)