1
00:00:03,000 --> 00:00:04,772
We implemented the functionality

2
00:00:05,272 --> 00:00:07,460
to turn "Dark Mode" on or off.

3
00:00:07,460 --> 00:00:10,814
And this happens on the client-side of course.

4
00:00:10,814 --> 00:00:12,855
There's some JavaScript code

5
00:00:12,855 --> 00:00:15,043
that's executed in the browser

6
00:00:15,043 --> 00:00:17,230
whenever we click this button.

7
00:00:18,021 --> 00:00:19,666
But we also know that

8
00:00:19,666 --> 00:00:22,327
our Next.js pages are pre-rendered

9
00:00:22,327 --> 00:00:23,815
on the server side.

10
00:00:24,471 --> 00:00:27,070
And in fact, if we look at the server logs

11
00:00:27,070 --> 00:00:29,607
we can see that, to render the AboutPage,

12
00:00:30,168 --> 00:00:32,766
our "ThemeSwitch" component function

13
00:00:32,766 --> 00:00:34,425
also ran on the server.

14
00:00:34,425 --> 00:00:36,878
This shouldn't come as a surprise,

15
00:00:36,878 --> 00:00:39,042
but it's the first time we use

16
00:00:39,042 --> 00:00:41,639
some state in one of our components,

17
00:00:41,639 --> 00:00:43,947
that is the "darkMode" variable.

18
00:00:43,947 --> 00:00:46,039
So it may be worth noting how

19
00:00:46,039 --> 00:00:47,410
the "useState" hook

20
00:00:47,410 --> 00:00:49,646
also gets called on the server.

21
00:00:49,646 --> 00:00:51,233
And when that happens,

22
00:00:51,233 --> 00:00:54,408
"useState" always returns the initial value,

23
00:00:54,408 --> 00:00:56,644
that is "false" for "darkMode".

24
00:00:57,937 --> 00:01:00,040
Now, another thing we've seen before

25
00:01:00,040 --> 00:01:01,500
is that when our app runs

26
00:01:01,500 --> 00:01:02,669
in development mode,

27
00:01:03,285 --> 00:01:05,248
every time we reload the page

28
00:01:05,248 --> 00:01:08,566
that page component is re-rendered on the server,

29
00:01:09,134 --> 00:01:12,299
including any other React components it uses,

30
00:01:12,299 --> 00:01:13,776
like the ThemeSwitch.

31
00:01:14,346 --> 00:01:15,566
But this doesn't happen

32
00:01:15,566 --> 00:01:17,369
when we run our app in production.

33
00:01:18,412 --> 00:01:20,291
Let's do an "npm run build",

34
00:01:20,291 --> 00:01:22,841
and generate the pages for production.

35
00:01:24,278 --> 00:01:25,975
If we look at the build log,

36
00:01:25,975 --> 00:01:28,096
when it generates the static pages,

37
00:01:29,045 --> 00:01:30,135
you can see that

38
00:01:30,135 --> 00:01:32,588
the "ThemeSwitch" component function

39
00:01:32,588 --> 00:01:34,496
was called during the build.

40
00:01:34,496 --> 00:01:37,426
And in fact it was executed multiple times,

41
00:01:37,426 --> 00:01:40,493
because that component is used in the NavBar,

42
00:01:40,493 --> 00:01:42,674
that's at the top of every page.

43
00:01:43,515 --> 00:01:45,804
Other than this, there isn't much new

44
00:01:45,804 --> 00:01:47,227
happening in the build,

45
00:01:47,227 --> 00:01:49,578
compared to what we saw the last time.

46
00:01:50,748 --> 00:01:52,015
Now, let's go and look

47
00:01:52,015 --> 00:01:53,398
inside the build folder.

48
00:01:53,956 --> 00:01:56,344
If we open the About page for example,

49
00:01:56,344 --> 00:01:57,915
just because it's the one

50
00:01:57,915 --> 00:01:59,612
we had open in the browser,

51
00:02:01,322 --> 00:02:03,248
as usual the page component

52
00:02:03,248 --> 00:02:05,389
has been pre-rendered to HTML,

53
00:02:05,389 --> 00:02:08,315
and this includes the "Dark Mode" button.

54
00:02:08,957 --> 00:02:10,551
Again, this is consistent

55
00:02:10,551 --> 00:02:13,039
with what we knew from previous videos.

56
00:02:13,603 --> 00:02:15,711
Now let's go and start the app

57
00:02:15,711 --> 00:02:17,046
in production mode,

58
00:02:17,046 --> 00:02:18,241
with "npm start".

59
00:02:21,135 --> 00:02:22,608
If we load the page now,

60
00:02:23,602 --> 00:02:24,461
you can see how

61
00:02:24,461 --> 00:02:26,637
nothing new gets logged on the server.

62
00:02:27,194 --> 00:02:28,331
Let me clear the terminal,

63
00:02:29,495 --> 00:02:31,620
and we can request the About page

64
00:02:31,620 --> 00:02:33,231
as many times as we like,

65
00:02:33,231 --> 00:02:35,550
but the server doesn't re-render it.

66
00:02:36,179 --> 00:02:37,382
It simply returns

67
00:02:37,382 --> 00:02:39,295
the pre-generated HTML file

68
00:02:39,295 --> 00:02:41,986
we just looked at in the build folder.

69
00:02:42,628 --> 00:02:43,778
Now, let's have a look

70
00:02:43,778 --> 00:02:45,032
at the Network requests.

71
00:02:48,228 --> 00:02:50,418
We know that, when we load the page

72
00:02:50,418 --> 00:02:53,296
the browser fetches the "about" HTML document,

73
00:02:53,859 --> 00:02:56,317
that contains the pre-rendered HTML.

74
00:02:56,817 --> 00:02:59,211
So the browser displays this HTML,

75
00:02:59,211 --> 00:03:01,535
and at this point our ThemeSwitch

76
00:03:01,535 --> 00:03:03,155
is just a plain button.

77
00:03:03,155 --> 00:03:06,253
It doesn't have any event handlers attached,

78
00:03:06,253 --> 00:03:07,803
so clicking the button

79
00:03:07,803 --> 00:03:09,915
wouldn't actually do anything.

80
00:03:10,768 --> 00:03:13,276
But, after loading the HTML document,

81
00:03:13,800 --> 00:03:15,302
the browser also loads

82
00:03:15,302 --> 00:03:17,145
all these JavaScript files.

83
00:03:17,145 --> 00:03:19,124
These files basically contain

84
00:03:19,124 --> 00:03:20,420
the React framework

85
00:03:20,420 --> 00:03:22,604
along with our application code.

86
00:03:22,604 --> 00:03:24,174
Next.js splits the code

87
00:03:24,174 --> 00:03:25,812
into multiple "js" files

88
00:03:25,812 --> 00:03:28,473
so the browser loads them more quickly,

89
00:03:28,473 --> 00:03:30,657
and we don't need to worry about

90
00:03:30,657 --> 00:03:32,636
what exactly is in each file,

91
00:03:33,750 --> 00:03:35,452
but just as an example,

92
00:03:35,452 --> 00:03:38,262
the code for our ThemeSwitch component

93
00:03:38,262 --> 00:03:40,555
will be in this "_app.js" file.

94
00:03:41,202 --> 00:03:42,675
So the browser executes

95
00:03:42,675 --> 00:03:44,916
the JavaScript code in these files.

96
00:03:45,480 --> 00:03:47,031
And it's at this point that

97
00:03:47,031 --> 00:03:48,524
these messages are printed

98
00:03:48,524 --> 00:03:49,845
to the browser console.

99
00:03:50,459 --> 00:03:52,094
But why are the components

100
00:03:52,094 --> 00:03:53,540
rendered by the browser

101
00:03:53,540 --> 00:03:56,306
if they were already rendered by the server?

102
00:03:56,306 --> 00:03:57,941
We touched on this before,

103
00:03:57,941 --> 00:04:00,267
but I didn't really fully explain it.

104
00:04:01,018 --> 00:04:02,034
We've seen that,

105
00:04:02,034 --> 00:04:04,508
after loading the initial HTML document

106
00:04:04,508 --> 00:04:06,285
our ThemeSwitch component is

107
00:04:06,285 --> 00:04:08,950
just a basic button with no functionality.

108
00:04:09,640 --> 00:04:12,688
Now, when the JavaScript code is executed,

109
00:04:12,688 --> 00:04:14,720
our React app is initialised

110
00:04:14,720 --> 00:04:17,188
by calling the "hydrate" function.

111
00:04:17,188 --> 00:04:18,784
In a normal React app,

112
00:04:18,784 --> 00:04:21,541
you typically call "ReactDOM.render()"

113
00:04:21,541 --> 00:04:23,211
to insert your app into

114
00:04:23,211 --> 00:04:25,751
an empty "div" element in the page.

115
00:04:25,751 --> 00:04:27,856
But with Next.js the page was

116
00:04:27,856 --> 00:04:30,396
already pre-rendered on the server,

117
00:04:30,396 --> 00:04:33,806
and the document already contains some elements

118
00:04:33,806 --> 00:04:37,290
like the "button" for our ThemeSwitch component.

119
00:04:37,290 --> 00:04:39,322
So we want to somehow attach

120
00:04:39,322 --> 00:04:42,660
our React components to the existing elements,

121
00:04:42,660 --> 00:04:44,402
making them interactive.

122
00:04:44,402 --> 00:04:46,942
This process is called "hydration".

123
00:04:48,457 --> 00:04:50,023
When "hydrating" our app,

124
00:04:50,023 --> 00:04:51,275
React will call our

125
00:04:51,275 --> 00:04:53,217
ThemeSwitch component function,

126
00:04:53,217 --> 00:04:55,659
among other components used in our app.

127
00:04:56,346 --> 00:04:57,724
It's at this point that

128
00:04:57,724 --> 00:04:59,580
this console message is logged.

129
00:05:00,139 --> 00:05:03,423
And when our ThemeSwitch component is hydrated,

130
00:05:03,423 --> 00:05:05,519
it's connected to the existing

131
00:05:05,519 --> 00:05:07,335
button element in the DOM.

132
00:05:07,335 --> 00:05:09,990
And it adds interactive functionality,

133
00:05:09,990 --> 00:05:11,597
for example it attaches

134
00:05:11,597 --> 00:05:14,461
an "onclick" event handler to the button.

135
00:05:15,310 --> 00:05:17,042
Thanks to this last step

136
00:05:17,042 --> 00:05:19,062
we can now click this button

137
00:05:19,062 --> 00:05:21,299
and turn "Dark Mode" on or off.

138
00:05:22,144 --> 00:05:24,207
It's important to understand

139
00:05:24,207 --> 00:05:25,828
this two step process:

140
00:05:25,828 --> 00:05:28,333
first the static HTML is rendered,

141
00:05:28,333 --> 00:05:31,870
and only in a separate step, called "hydration",

142
00:05:31,870 --> 00:05:34,006
the client-side functionality

143
00:05:34,006 --> 00:05:35,701
of our React components

144
00:05:35,701 --> 00:05:38,427
is attached to the existing document.

145
00:05:39,370 --> 00:05:42,540
We can prove this by making our usual experiment

146
00:05:42,540 --> 00:05:44,918
and turn JavaScript off temporarily.

147
00:05:46,502 --> 00:05:48,675
Let me show the Network requests again.

148
00:05:49,368 --> 00:05:51,039
If we reload the page now,

149
00:05:51,039 --> 00:05:53,673
you can see that all the JavaScript files

150
00:05:53,673 --> 00:05:54,830
have been blocked,

151
00:05:54,830 --> 00:05:56,629
so they haven't been loaded.

152
00:05:57,321 --> 00:06:00,050
And our page still looks the same initially,

153
00:06:00,050 --> 00:06:01,972
because we see the static HTML,

154
00:06:02,534 --> 00:06:04,695
but obviously no JavaScript code

155
00:06:04,695 --> 00:06:05,843
will be executed.

156
00:06:06,410 --> 00:06:08,484
As a result our "Dark Mode" button

157
00:06:08,484 --> 00:06:09,826
doesn't actually work.

158
00:06:10,387 --> 00:06:11,804
I can try clicking on it,

159
00:06:11,804 --> 00:06:12,938
but nothing happens.

160
00:06:13,494 --> 00:06:16,555
So that's why we need the "hydration" step,

161
00:06:16,555 --> 00:06:19,331
to enable any interactive functionality

162
00:06:19,331 --> 00:06:21,111
that we have in our page.

163
00:06:21,111 --> 00:06:24,030
Pre-rendering HTML on the server is great

164
00:06:24,030 --> 00:06:26,450
for the initial read-only content,

165
00:06:26,450 --> 00:06:29,511
but to provide any sort of user interaction

166
00:06:29,511 --> 00:06:31,575
we still need JavaScript code

167
00:06:31,575 --> 00:06:33,212
running in the browser.

168
00:06:33,212 --> 00:06:35,988
And that's why all our React components

169
00:06:35,988 --> 00:06:37,341
are rendered twice:

170
00:06:37,341 --> 00:06:38,764
first on the server,

171
00:06:38,764 --> 00:06:41,184
and then again on the client side.

