1
00:00:03,000 --> 00:00:05,002
At the end of the last video

2
00:00:05,002 --> 00:00:07,291
I suggested an exercise for you,

3
00:00:07,863 --> 00:00:10,955
that is to implement this new product page.

4
00:00:11,455 --> 00:00:13,829
Now let's see together how to do that.

5
00:00:14,329 --> 00:00:15,716
For a start we'll need

6
00:00:15,716 --> 00:00:18,176
the usual React component for our page.

7
00:00:20,329 --> 00:00:22,569
And it needs to be the "default" export.

8
00:00:24,862 --> 00:00:27,747
As for the content rendered by the component

9
00:00:27,747 --> 00:00:30,108
I'm going to copy the same structure

10
00:00:30,108 --> 00:00:31,682
we have in our HomePage.

11
00:00:32,462 --> 00:00:34,601
But we don't want a list of products.

12
00:00:35,101 --> 00:00:38,343
Let's change the title to say "Product" for now.

13
00:00:38,843 --> 00:00:40,978
And we'll also need to import

14
00:00:40,978 --> 00:00:42,894
any component we use here,

15
00:00:42,894 --> 00:00:44,882
that is "Head" and "Title".

16
00:00:45,530 --> 00:00:46,620
Ok, if we save now

17
00:00:46,620 --> 00:00:48,983
we should be able to click on a product

18
00:00:48,983 --> 00:00:50,255
and see the new page.

19
00:00:50,877 --> 00:00:52,899
Of course at the moment it will display

20
00:00:52,899 --> 00:00:54,870
the same content for all the products.

21
00:00:55,777 --> 00:00:58,366
To make it return different content

22
00:00:58,366 --> 00:00:59,994
for different products

23
00:00:59,994 --> 00:01:02,953
we'll need to write the "getStaticPaths"

24
00:01:02,953 --> 00:01:05,247
and "getStaticProps" functions.

25
00:01:05,968 --> 00:01:08,075
Starting with "getStaticPaths"

26
00:01:08,075 --> 00:01:11,446
this returns an object with an array of "paths",

27
00:01:12,016 --> 00:01:14,544
and a "fallback" flag, that for now

28
00:01:14,544 --> 00:01:17,793
I'll set to "false" like in our Blog example.

29
00:01:18,365 --> 00:01:20,682
Now, the "paths" array should contain

30
00:01:20,682 --> 00:01:22,498
one element for each product,

31
00:01:23,061 --> 00:01:25,975
but to do that we first need the list of products.

32
00:01:25,975 --> 00:01:28,539
We know that we already have a function here

33
00:01:28,539 --> 00:01:29,996
for exactly that purpose.

34
00:01:30,612 --> 00:01:34,433
So in "getStaticPaths" we want to get the "products"

35
00:01:34,433 --> 00:01:37,959
by awaiting the result of calling "getProducts".

36
00:01:38,533 --> 00:01:40,187
And for some strange reason

37
00:01:40,187 --> 00:01:42,209
auto-import isn't working for me,

38
00:01:42,209 --> 00:01:45,027
so I'll have to import that function manually.

39
00:01:45,665 --> 00:01:47,428
We need to go up two levels

40
00:01:47,428 --> 00:01:49,712
and then into "lib" and "products".

41
00:01:52,631 --> 00:01:54,605
Ok, once we have the "products"

42
00:01:54,605 --> 00:01:56,197
we can create the "paths"

43
00:01:56,197 --> 00:01:58,553
by mapping over the "products" array,

44
00:02:00,331 --> 00:02:02,216
and transform each "product"

45
00:02:02,216 --> 00:02:05,177
into an object that has a "params" property.

46
00:02:05,744 --> 00:02:07,980
And the name of the parameter needs to match

47
00:02:07,980 --> 00:02:09,505
what we used in the file name,

48
00:02:10,055 --> 00:02:11,886
so it must be called "id",

49
00:02:11,886 --> 00:02:14,631
and its value will be the "product.id".

50
00:02:15,201 --> 00:02:17,452
Now, there's something we need to

51
00:02:17,452 --> 00:02:18,953
be careful about here:

52
00:02:18,953 --> 00:02:21,749
the "id" returned by the CMS is a number.

53
00:02:22,385 --> 00:02:25,193
but the path parameter must be a string,

54
00:02:25,193 --> 00:02:27,930
because it's passed as part of the URL.

55
00:02:28,500 --> 00:02:31,409
So we need to convert the number to a string,

56
00:02:31,409 --> 00:02:33,283
otherwise we'll get an error.

57
00:02:34,600 --> 00:02:36,681
Ok, the next step is to write

58
00:02:36,681 --> 00:02:38,691
a "getStaticProps" function,

59
00:02:39,633 --> 00:02:41,209
so we can pass some props

60
00:02:41,209 --> 00:02:42,595
to the React component

61
00:02:42,595 --> 00:02:44,989
with the product data to be displayed.

62
00:02:47,066 --> 00:02:48,641
"getStaticProps" returns

63
00:02:48,641 --> 00:02:50,478
an object with some "props".

64
00:02:52,499 --> 00:02:55,065
And what we want to pass in the "props"

65
00:02:55,065 --> 00:02:56,512
is the "product" data.

66
00:02:57,077 --> 00:02:58,570
So what we need now is

67
00:02:58,570 --> 00:03:01,623
a way to fetch the data for a single product.

68
00:03:02,190 --> 00:03:04,141
In our "lib" module at the moment

69
00:03:04,141 --> 00:03:06,978
we only have a function to get all the products.

70
00:03:07,537 --> 00:03:09,399
Let's add a new function to fetch

71
00:03:09,399 --> 00:03:11,091
the data for a single product,

72
00:03:13,903 --> 00:03:16,911
and in this case we need the "id" as an argument.

73
00:03:17,411 --> 00:03:20,109
We can copy the "fetch" call from the other function.

74
00:03:21,077 --> 00:03:24,052
But in this case we want a template string here,

75
00:03:25,610 --> 00:03:28,618
so we can insert the "id" into the URL.

76
00:03:29,118 --> 00:03:31,185
And rather than an array of "products"

77
00:03:31,185 --> 00:03:33,360
this response contains a single product,

78
00:03:33,914 --> 00:03:36,722
that's what we want to return from this function,

79
00:03:36,722 --> 00:03:39,587
but I'm going to transform it using "stripProduct"

80
00:03:39,587 --> 00:03:41,421
to keep only the fields we need.

81
00:03:42,035 --> 00:03:44,204
Ok, now that we have this function

82
00:03:44,204 --> 00:03:46,500
we can call it from "getStaticProps"

83
00:03:46,500 --> 00:03:48,158
to get the "product" data.

84
00:03:50,601 --> 00:03:53,053
And again, I'll have to import this manually

85
00:03:53,053 --> 00:03:55,393
because it's not doing that automatically.

86
00:03:56,834 --> 00:03:58,853
Not sure why sometimes it doesn't work,

87
00:03:58,853 --> 00:03:59,992
but it doesn't matter.

88
00:04:00,543 --> 00:04:02,603
Now, when calling "getProduct"

89
00:04:02,603 --> 00:04:04,319
we need to pass the "id".

90
00:04:04,887 --> 00:04:06,974
And we are in fact passing that

91
00:04:06,974 --> 00:04:09,599
to this function from "getStaticPaths".

92
00:04:10,166 --> 00:04:12,397
Here we receive the "path" object

93
00:04:12,397 --> 00:04:14,222
that contains the "params",

94
00:04:14,222 --> 00:04:16,047
where we can find the "id".

95
00:04:16,682 --> 00:04:18,855
So that's what we pass to "getProduct".

96
00:04:19,682 --> 00:04:22,591
And at this point "getStaticProps" should be ready.

97
00:04:23,648 --> 00:04:26,143
The next step is to extract the "product"

98
00:04:26,143 --> 00:04:29,003
from the "props" passed to the React component,

99
00:04:29,563 --> 00:04:31,369
so that we can finally display

100
00:04:31,369 --> 00:04:33,476
the product properties in the page,

101
00:04:33,476 --> 00:04:35,041
starting with the "title".

102
00:04:35,661 --> 00:04:36,940
And if we save now,

103
00:04:36,940 --> 00:04:38,891
we'll need to reload the page

104
00:04:38,891 --> 00:04:41,044
to execute the server-side code,

105
00:04:41,044 --> 00:04:43,130
but we can now see "Aloe Vera".

106
00:04:43,831 --> 00:04:45,303
And if we select a different product,

107
00:04:46,497 --> 00:04:48,716
of course we'll see a different title.

108
00:04:48,716 --> 00:04:50,700
Let's add the description as well.

109
00:04:51,259 --> 00:04:53,402
but for that we'll need to change

110
00:04:53,402 --> 00:04:54,637
the data tier code.

111
00:04:55,201 --> 00:04:56,854
Let's add the "description" to

112
00:04:56,854 --> 00:04:59,058
the product fields that we pass through.

113
00:05:00,834 --> 00:05:03,621
We know that the CMS response does include

114
00:05:03,621 --> 00:05:05,080
a "description" field.

115
00:05:05,646 --> 00:05:07,920
So now we could add a simple paragraph

116
00:05:07,920 --> 00:05:10,133
displaying the "product.description".

117
00:05:10,947 --> 00:05:12,084
And if we try this out,

118
00:05:13,747 --> 00:05:17,040
here we can see a long description for Aloe Vera.

119
00:05:17,540 --> 00:05:19,011
And if we select another product,

120
00:05:19,011 --> 00:05:20,972
of course we'll see a different description.

121
00:05:21,516 --> 00:05:23,682
Ok, so this is the implementation

122
00:05:23,682 --> 00:05:24,995
for our ProductPage.

123
00:05:25,682 --> 00:05:27,863
It's a dynamic route, so we need

124
00:05:27,863 --> 00:05:30,725
"getStaticPaths" to list all the URL paths

125
00:05:30,725 --> 00:05:32,565
for the available products,

126
00:05:33,201 --> 00:05:35,677
and "getStaticProps" to fetch the data

127
00:05:35,677 --> 00:05:37,370
for an individual product.

128
00:05:37,370 --> 00:05:39,455
Data that we pass in the "props"

129
00:05:39,455 --> 00:05:41,930
to the component where it's displayed.

