1
00:00:03,000 --> 00:00:05,514
We've seen how to fetch the products

2
00:00:05,514 --> 00:00:08,378
on the server side, using getStaticProps.

3
00:00:08,948 --> 00:00:10,938
Now let's look at "Option 2",

4
00:00:10,938 --> 00:00:14,026
that is fetching the data on the client side.

5
00:00:14,595 --> 00:00:16,600
Let's load our "index-2" page.

6
00:00:16,600 --> 00:00:18,672
We're working on separate pages

7
00:00:18,672 --> 00:00:21,747
so we can then compare the various approaches.

8
00:00:22,381 --> 00:00:24,077
And this page still shows

9
00:00:24,077 --> 00:00:25,773
these hard-coded products

10
00:00:26,341 --> 00:00:27,795
that we want to remove

11
00:00:27,795 --> 00:00:30,837
and replace with the data coming from the CMS.

12
00:00:31,403 --> 00:00:34,367
Now, in this case we want to fetch the data

13
00:00:34,367 --> 00:00:36,504
when this component is mounted,

14
00:00:36,504 --> 00:00:39,054
as you would do in a plain React app.

15
00:00:39,692 --> 00:00:41,170
So first of all we need

16
00:00:41,170 --> 00:00:43,419
a state variable called "products",

17
00:00:43,419 --> 00:00:46,247
that we can create with the "useState" hook.

18
00:00:47,591 --> 00:00:48,980
And as the initial value

19
00:00:48,980 --> 00:00:50,542
we can pass an empty array.

20
00:00:51,100 --> 00:00:53,566
Then we can call the "useEffect" hook

21
00:00:53,566 --> 00:00:55,700
to execute a function as soon as

22
00:00:55,700 --> 00:00:57,433
this component is mounted.

23
00:00:58,067 --> 00:01:01,375
And we want to pass an empty array of dependencies

24
00:01:01,375 --> 00:01:04,617
to make sure this function is only executed once.

25
00:01:05,183 --> 00:01:07,174
Inside this function we want to

26
00:01:07,174 --> 00:01:09,999
make the HTTP request to fetch the products.

27
00:01:10,563 --> 00:01:12,419
So we should call this URL,

28
00:01:12,919 --> 00:01:15,898
but we've already written a function to do that:

29
00:01:15,898 --> 00:01:18,690
this module exports a "getProducts" function.

30
00:01:19,252 --> 00:01:22,344
So we can simply call that same function

31
00:01:22,344 --> 00:01:24,353
from our client side code.

32
00:01:24,353 --> 00:01:26,440
Now, "getProducts" is async

33
00:01:26,440 --> 00:01:28,295
so it returns a Promise.

34
00:01:29,026 --> 00:01:31,486
Rather than using "await" this time

35
00:01:31,486 --> 00:01:34,155
I'll simply call "then" on the Promise

36
00:01:34,155 --> 00:01:37,809
and pass "setProducts" to update the state variable.

37
00:01:38,449 --> 00:01:41,295
Just to be clear, this is the equivalent of

38
00:01:41,295 --> 00:01:42,751
receiving the products

39
00:01:42,751 --> 00:01:45,001
and passing them to "setProducts".

40
00:01:45,633 --> 00:01:48,809
We can simply pass the "setProducts" function directly.

41
00:01:49,309 --> 00:01:52,163
Anyway, this is how we can fetch the data

42
00:01:52,163 --> 00:01:53,485
on the client side.

43
00:01:54,054 --> 00:01:55,730
If we save these changes,

44
00:01:55,730 --> 00:01:57,674
we'll see the "real" products

45
00:01:57,674 --> 00:01:59,149
displayed on the page.

46
00:01:59,149 --> 00:02:01,294
So the end result looks the same

47
00:02:01,294 --> 00:02:02,835
as with our "Option 1".

48
00:02:02,835 --> 00:02:05,516
But the way it works is a bit different.

49
00:02:06,351 --> 00:02:08,122
Let me show the server logs as well.

50
00:02:08,917 --> 00:02:10,054
When we load this page,

51
00:02:11,883 --> 00:02:13,179
what happens is that

52
00:02:13,179 --> 00:02:16,031
the page is pre-rendered on the server side,

53
00:02:16,595 --> 00:02:19,235
but "products" is set to its initial value,

54
00:02:19,235 --> 00:02:20,646
that is an empty array.

55
00:02:21,207 --> 00:02:23,061
The HomePage component is

56
00:02:23,061 --> 00:02:25,137
hydrated on the client side,

57
00:02:25,137 --> 00:02:27,954
again with an empty array as products.

58
00:02:27,954 --> 00:02:30,326
Then the "useEffect" hooks runs,

59
00:02:30,326 --> 00:02:32,624
we fetch the data from the CMS,

60
00:02:32,624 --> 00:02:36,034
and at that point the component is re-rendered

61
00:02:36,034 --> 00:02:39,445
with an array of 6 elements as the "products".

62
00:02:40,389 --> 00:02:44,400
This is how a typical client-side React app works.

63
00:02:44,900 --> 00:02:46,401
Now, let's compare this

64
00:02:46,401 --> 00:02:48,228
to the server side approach,

65
00:02:48,793 --> 00:02:51,818
that is when we load our "index-1" page.

66
00:02:53,826 --> 00:02:55,748
In this case, as we know,

67
00:02:55,748 --> 00:02:59,745
the data is fetched in the "getStaticProps" function

68
00:02:59,745 --> 00:03:01,513
so when the HomePage is

69
00:03:01,513 --> 00:03:04,126
pre-rendered to HTML on the server

70
00:03:04,126 --> 00:03:07,354
it already includes the real product data.

71
00:03:08,161 --> 00:03:11,083
And then, as usual, the component is hydrated

72
00:03:11,083 --> 00:03:13,745
on the client side, using the same props.

73
00:03:14,309 --> 00:03:17,048
We can see that same difference more clearly

74
00:03:17,048 --> 00:03:19,227
if we look at the network requests.

75
00:03:20,175 --> 00:03:22,561
When we load the "index-1" page,

76
00:03:22,561 --> 00:03:26,288
we know that the server returns the HTML document.

77
00:03:26,862 --> 00:03:29,070
And if we look at the Response tab

78
00:03:29,070 --> 00:03:30,693
we can see the full HTML.

79
00:03:32,662 --> 00:03:34,535
Let's format it with "Pretty-print",

80
00:03:36,595 --> 00:03:38,362
and here we can see how

81
00:03:38,362 --> 00:03:41,282
the pre-rendered HTML already includes

82
00:03:41,282 --> 00:03:43,510
all the products in the list.

83
00:03:44,163 --> 00:03:46,490
We know from early in the course

84
00:03:46,490 --> 00:03:48,526
that pre-rendering is one of

85
00:03:48,526 --> 00:03:50,780
the main advantages of Next.js,

86
00:03:50,780 --> 00:03:54,197
but here we're focusing on this particular data

87
00:03:54,197 --> 00:03:56,378
that's rendered inside a list,

88
00:03:56,378 --> 00:03:58,705
so it's just a part of the page.

89
00:03:59,568 --> 00:04:02,100
If we do the same experiment with "index-2"

90
00:04:02,100 --> 00:04:04,456
of course we'll see something different.

91
00:04:05,014 --> 00:04:07,421
The HTML document will still have been

92
00:04:07,421 --> 00:04:09,130
pre-rendered by the server,

93
00:04:10,547 --> 00:04:13,180
but if we go and look for that same

94
00:04:13,180 --> 00:04:14,985
"ul" element in the HTML

95
00:04:15,560 --> 00:04:17,433
in this case the list is empty.

96
00:04:17,933 --> 00:04:20,077
Because, as we've seen in the logs,

97
00:04:20,077 --> 00:04:23,019
it was rendered with an empty array of products.

98
00:04:23,580 --> 00:04:25,870
But then, when the browser executes

99
00:04:25,870 --> 00:04:28,095
the JavaScript code for this page,

100
00:04:28,660 --> 00:04:31,970
this will make an HTTP request to the CMS API.

101
00:04:32,470 --> 00:04:34,114
We can see the URL here.

102
00:04:34,114 --> 00:04:37,195
This is actually another important difference

103
00:04:37,195 --> 00:04:39,728
compared to the server-side approach:

104
00:04:39,728 --> 00:04:42,466
if we do the fetching on the client side

105
00:04:42,466 --> 00:04:44,315
that means that our CMS API

106
00:04:44,315 --> 00:04:46,848
needs to be accessible to the public,

107
00:04:46,848 --> 00:04:49,997
because it will be called from the web browser

108
00:04:49,997 --> 00:04:52,325
of anybody who visits our website.

109
00:04:53,304 --> 00:04:55,747
While in the server-side approach,

110
00:04:55,747 --> 00:04:58,548
the CMS API only needs to be accessible

111
00:04:58,548 --> 00:05:01,708
from the server when we run our Next.js app.

112
00:05:01,708 --> 00:05:04,582
In fact, if we build our site statically

113
00:05:04,582 --> 00:05:08,101
the CMS only needs to be available at build time.

114
00:05:08,101 --> 00:05:10,974
So that's another thing to keep in mind.

115
00:05:11,833 --> 00:05:14,207
Now, if we look at the JSON response

116
00:05:14,707 --> 00:05:17,119
since we're calling the CMS directly

117
00:05:17,119 --> 00:05:20,334
we always load all the data returned by the CMS,

118
00:05:20,334 --> 00:05:22,746
including many fields we don't need.

119
00:05:23,379 --> 00:05:26,349
While if we fetch the data on the server side

120
00:05:26,349 --> 00:05:28,658
we can keep only the fields we need

121
00:05:28,658 --> 00:05:30,968
and return less data to the client.

122
00:05:31,600 --> 00:05:33,642
So that's another potential advantage

123
00:05:33,642 --> 00:05:35,188
of the server-side approach:

124
00:05:36,700 --> 00:05:39,290
we can send less data to the client,

125
00:05:39,290 --> 00:05:41,521
making our app slightly faster.

126
00:05:41,521 --> 00:05:43,968
So based on what we've seen so far

127
00:05:43,968 --> 00:05:47,278
it looks like fetching data on the server side

128
00:05:47,278 --> 00:05:49,221
has quite a few advantages.

129
00:05:49,221 --> 00:05:52,315
Our page can be fully pre-rendered to HTML,

130
00:05:52,315 --> 00:05:54,474
which makes it faster to load,

131
00:05:54,474 --> 00:05:57,496
and can also be useful for search engines.

132
00:05:57,496 --> 00:06:00,159
We only need the CMS to be accessible

133
00:06:00,159 --> 00:06:03,397
from the server where we run our Next.js app,

134
00:06:03,397 --> 00:06:05,916
and not exposed to the whole world.

135
00:06:05,916 --> 00:06:08,146
And we can also filter the data

136
00:06:08,146 --> 00:06:10,593
before returning it to the client,

137
00:06:10,593 --> 00:06:11,888
reducing its size.

138
00:06:11,888 --> 00:06:14,695
But there is also a potential advantage

139
00:06:14,695 --> 00:06:16,854
with the client side approach:

140
00:06:16,854 --> 00:06:19,372
by fetching the data in the browser

141
00:06:19,372 --> 00:06:20,884
directly from the CMS

142
00:06:20,884 --> 00:06:23,834
we can be sure that the page will display

143
00:06:23,834 --> 00:06:25,705
the latest data available.

144
00:06:25,705 --> 00:06:28,224
If we take the server side approach

145
00:06:28,224 --> 00:06:30,886
and generate all our pages statically

146
00:06:30,886 --> 00:06:32,685
what happens if we change

147
00:06:32,685 --> 00:06:34,700
the product data in the CMS?

148
00:06:34,700 --> 00:06:37,579
Statically generated pages never change,

149
00:06:37,579 --> 00:06:40,961
so our website would keep showing the old data.

150
00:06:40,961 --> 00:06:43,407
This is potentially a big problem,

151
00:06:43,407 --> 00:06:46,790
and we'll talk more about it in the next video.

