1
00:00:03,000 --> 00:00:05,780
We're currently using dynamic rendering

2
00:00:05,780 --> 00:00:08,085
to make sure our pages display

3
00:00:08,085 --> 00:00:10,314
the latest data from the CMS.

4
00:00:10,390 --> 00:00:13,126
But the downside of this approach is that

5
00:00:13,126 --> 00:00:15,530
the server regenerates each page

6
00:00:15,530 --> 00:00:17,483
every time it's requested,

7
00:00:17,558 --> 00:00:19,786
even though the data in the CMS

8
00:00:19,786 --> 00:00:21,655
doesn't change very often.

9
00:00:21,727 --> 00:00:24,043
For this reason Next.js provides

10
00:00:24,043 --> 00:00:26,359
a feature called "revalidation",

11
00:00:26,432 --> 00:00:29,080
that lets us generate static pages,

12
00:00:29,080 --> 00:00:32,320
but then "revalidate" them at runtime,

13
00:00:32,320 --> 00:00:35,219
which effectively means regenerate them.

14
00:00:35,219 --> 00:00:38,175
Let's start with "Background Revalidation",

15
00:00:38,175 --> 00:00:40,076
which regenerates the pages

16
00:00:40,076 --> 00:00:41,696
at a specific interval,

17
00:00:41,767 --> 00:00:44,583
like every 60 seconds in this example.

18
00:00:44,583 --> 00:00:47,190
We can configure this in our page file,

19
00:00:47,190 --> 00:00:50,300
by exporting a property called "revalidate".

20
00:00:50,300 --> 00:00:53,123
Or we can also enable it when calling "fetch",

21
00:00:53,123 --> 00:00:55,558
but we'll cover that in the next video.

22
00:00:55,558 --> 00:00:59,181
Let's start by configuring it at the page level.

23
00:00:59,181 --> 00:01:00,983
Now, let's assume that

24
00:01:00,983 --> 00:01:04,177
we only want to be able to publish new reviews,

25
00:01:04,177 --> 00:01:07,832
we don't really plan to modify existing content.

26
00:01:07,832 --> 00:01:09,717
If that's the case, then we

27
00:01:09,717 --> 00:01:11,324
only need to revalidate

28
00:01:11,393 --> 00:01:14,072
the Home and Reviews pages.

29
00:01:14,072 --> 00:01:15,951
Because that's where we show

30
00:01:15,951 --> 00:01:17,561
the most recent entries,

31
00:01:17,628 --> 00:01:20,124
and we want them to load fresh data

32
00:01:20,124 --> 00:01:21,978
to include the new review.

33
00:01:22,049 --> 00:01:24,683
As for the individual ReviewPage,

34
00:01:24,683 --> 00:01:27,184
we've seen at the start of this section that

35
00:01:27,184 --> 00:01:29,166
Next.js can generate a new

36
00:01:29,166 --> 00:01:31,147
review page automatically,

37
00:01:31,223 --> 00:01:33,414
if we simply use the default

38
00:01:33,414 --> 00:01:35,371
"dynamicParams" behavior.

39
00:01:35,449 --> 00:01:38,314
We just need to remove "force-dynamic"

40
00:01:38,314 --> 00:01:39,445
from this page.

41
00:01:39,521 --> 00:01:42,372
So, for this video I'll make this assumption:

42
00:01:42,372 --> 00:01:45,125
that we only want to publish new reviews,

43
00:01:45,125 --> 00:01:47,392
and not update existing ones.

44
00:01:47,392 --> 00:01:50,137
Let me delete this "cuphead-2" by the way,

45
00:01:50,137 --> 00:01:52,412
that we only created for testing.

46
00:01:52,412 --> 00:01:54,987
We could restrict our collaborators

47
00:01:54,987 --> 00:01:56,900
to only create new reviews

48
00:01:56,974 --> 00:01:59,689
by configuring the Roles in Strapi.

49
00:01:59,689 --> 00:02:01,565
Each user has a role,

50
00:02:01,565 --> 00:02:04,011
like "Editor", that's predefined,

51
00:02:04,011 --> 00:02:06,792
and here you can configure permissions.

52
00:02:06,792 --> 00:02:09,514
So we could let editors Create,

53
00:02:09,514 --> 00:02:11,798
Read, and Publish reviews,

54
00:02:11,885 --> 00:02:14,433
but not Update or Delete them,

55
00:02:14,433 --> 00:02:17,033
so we can be sure nobody will modify

56
00:02:17,033 --> 00:02:19,344
any review after it's published,

57
00:02:19,416 --> 00:02:21,615
and therefore in our Next.js app

58
00:02:21,615 --> 00:02:23,470
we only need to worry about

59
00:02:23,539 --> 00:02:27,029
updating our pages to display new reviews.

60
00:02:27,029 --> 00:02:29,180
Anyway, for our tests we won't

61
00:02:29,180 --> 00:02:31,188
actually use separate users.

62
00:02:31,260 --> 00:02:33,344
We always log in as "admin",

63
00:02:33,344 --> 00:02:35,204
that has all permissions.

64
00:02:35,278 --> 00:02:37,250
Let's go back to our code now.

65
00:02:37,817 --> 00:02:39,693
As I mentioned, if we're only

66
00:02:39,693 --> 00:02:41,310
going to add new reviews,

67
00:02:41,375 --> 00:02:43,512
then in this page we can simply

68
00:02:43,512 --> 00:02:45,098
remove "force-dynamic",

69
00:02:45,167 --> 00:02:48,765
and also re-enable "generateStaticParams".

70
00:02:48,765 --> 00:02:51,169
This way the build will statically

71
00:02:51,169 --> 00:02:53,573
generate all the existing reviews.

72
00:02:53,643 --> 00:02:56,623
But if we publish a new review in the CMS

73
00:02:56,623 --> 00:02:59,139
Next.js will automatically render

74
00:02:59,139 --> 00:03:00,892
the new page on demand,

75
00:03:00,968 --> 00:03:03,829
thanks to the "dynamicParams" feature.

76
00:03:03,829 --> 00:03:06,360
Now, let's think about the HomePage.

77
00:03:06,360 --> 00:03:09,003
We no longer want this to be "dynamic",

78
00:03:09,003 --> 00:03:12,146
but we want it to "revalidate" periodically,

79
00:03:12,146 --> 00:03:14,361
so from time to time Next.js

80
00:03:14,361 --> 00:03:16,340
will regenerate this page

81
00:03:16,419 --> 00:03:19,341
fetching the latest data from the CMS.

82
00:03:19,341 --> 00:03:23,082
The "revalidate" value is a number of seconds.

83
00:03:23,082 --> 00:03:26,093
If we set it to 30 seconds for example,

84
00:03:26,093 --> 00:03:28,562
once it's generated, this page

85
00:03:28,562 --> 00:03:30,949
will be valid for 30 seconds.

86
00:03:31,031 --> 00:03:33,404
If the server receives a request

87
00:03:33,404 --> 00:03:37,417
and finds thatÂ the page is older than 30 seconds

88
00:03:37,417 --> 00:03:40,527
then it will re-render it in the background.

89
00:03:40,527 --> 00:03:42,650
We'll see this in action in a minute.

90
00:03:42,650 --> 00:03:45,677
Now, I'm using a pretty short interval here

91
00:03:45,677 --> 00:03:47,895
just to make it easier to test.

92
00:03:47,895 --> 00:03:50,858
But, in production you may want to set it to

93
00:03:50,858 --> 00:03:54,074
maybe 5 minutes, or at least 1 minute,

94
00:03:54,074 --> 00:03:57,907
so the page will be updated, but not too often.

95
00:03:57,907 --> 00:03:59,614
Anyway, we want to do the

96
00:03:59,614 --> 00:04:01,321
same for the ReviewsPage,

97
00:04:01,390 --> 00:04:04,100
revalidate it every 30 seconds.

98
00:04:04,100 --> 00:04:06,887
So if we add a new entry to the CMS

99
00:04:06,887 --> 00:04:09,137
it will be displayed in this page,

100
00:04:09,137 --> 00:04:10,660
after a short interval.

101
00:04:10,726 --> 00:04:12,545
To test this feature, we need

102
00:04:12,545 --> 00:04:14,112
to do a production build,

103
00:04:14,175 --> 00:04:15,674
because we know that

104
00:04:15,953 --> 00:04:18,642
the dev server always regenerates

105
00:04:18,642 --> 00:04:20,353
each page every time.

106
00:04:21,466 --> 00:04:24,252
Ok. All routes appear to be static

107
00:04:24,252 --> 00:04:25,973
in the build summary.

108
00:04:26,055 --> 00:04:29,086
But that doesn't really tell the full story,

109
00:04:29,086 --> 00:04:31,267
because yes they are static,

110
00:04:31,267 --> 00:04:34,495
but they will also be regenerated periodically.

111
00:04:34,495 --> 00:04:36,857
Let's see exactly how it works.

112
00:04:36,857 --> 00:04:38,588
Let me clear the logs.

113
00:04:38,617 --> 00:04:40,653
All pages have been statically

114
00:04:40,653 --> 00:04:42,486
generated during the build,

115
00:04:42,554 --> 00:04:44,801
so if we load them in the browser

116
00:04:44,801 --> 00:04:46,852
we won't see any "rendering"

117
00:04:46,852 --> 00:04:48,903
messages in the server logs.

118
00:04:48,977 --> 00:04:52,406
But now let's go and add a new review in the CMS.

119
00:04:52,406 --> 00:04:55,094
I'll just duplicate an existing entry,

120
00:04:55,094 --> 00:04:56,949
let's take "Subnautica",

121
00:04:56,949 --> 00:04:59,539
then change it to "subnautica-2",

122
00:04:59,539 --> 00:05:02,357
and Save and Publish the new entry.

123
00:05:02,357 --> 00:05:04,935
At this point, if we go back to our website,

124
00:05:05,314 --> 00:05:07,779
and reload the Reviews page,

125
00:05:07,779 --> 00:05:10,422
it's not showing the new entry yet,

126
00:05:10,422 --> 00:05:13,082
because it's been less than 30 seconds

127
00:05:13,082 --> 00:05:15,181
since this page was generated.

128
00:05:15,251 --> 00:05:17,490
So we need to wait a few seconds,

129
00:05:17,490 --> 00:05:18,780
and then try again.

130
00:05:18,847 --> 00:05:20,481
You can see in the logs that

131
00:05:20,481 --> 00:05:23,421
it rendered the ReviewsPage component,

132
00:05:23,421 --> 00:05:25,735
and the data returned by Strapi

133
00:05:25,735 --> 00:05:28,969
includes the new "subnautica-2" slug.

134
00:05:28,969 --> 00:05:31,589
It then rendered some other pages as well,

135
00:05:31,589 --> 00:05:33,903
because of link prefetching.

136
00:05:33,903 --> 00:05:36,235
However, in the browser we still

137
00:05:36,235 --> 00:05:38,057
don't see "Subnautica 2".

138
00:05:38,129 --> 00:05:39,680
That seems weird.

139
00:05:39,680 --> 00:05:41,670
What's going on here is that

140
00:05:41,670 --> 00:05:45,425
Next.js does "background revalidation".

141
00:05:45,425 --> 00:05:48,347
This means that, if it receives a request

142
00:05:48,347 --> 00:05:50,770
for a page that's no longer valid,

143
00:05:50,841 --> 00:05:54,475
it will regenerate it, but in the background.

144
00:05:54,475 --> 00:05:56,739
It still returns the old page

145
00:05:56,739 --> 00:05:58,378
to the browser first,

146
00:05:58,456 --> 00:06:01,801
so the user doesn't have to wait for the response,

147
00:06:01,801 --> 00:06:03,822
and then it generates the new

148
00:06:03,822 --> 00:06:05,356
page in the background

149
00:06:05,425 --> 00:06:08,643
to have it ready for subsequent requests.

150
00:06:08,643 --> 00:06:11,023
So, if we reload the page again,

151
00:06:11,023 --> 00:06:14,714
this time we do see "Subnautica 2" in the list.

152
00:06:14,714 --> 00:06:17,209
Note that the server didn't render

153
00:06:17,209 --> 00:06:19,557
the ReviewsPage component again.

154
00:06:19,630 --> 00:06:22,634
It simply returned the page it generated

155
00:06:22,634 --> 00:06:24,662
after our previous request.

156
00:06:24,738 --> 00:06:28,306
So, keep this in mind when testing your pages:

157
00:06:28,306 --> 00:06:31,791
the first request that triggers revalidation

158
00:06:31,791 --> 00:06:34,288
still receives the old page,

159
00:06:34,288 --> 00:06:37,424
but it will cause a new page to be generated

160
00:06:37,424 --> 00:06:40,680
and you can see it if you make a second request.

161
00:06:40,680 --> 00:06:42,858
Now, if we go to the Home page,

162
00:06:42,858 --> 00:06:46,292
we can see that this one has been updated as well.

163
00:06:46,292 --> 00:06:48,786
And if we open the new review page,

164
00:06:48,786 --> 00:06:50,248
this also works.

165
00:06:50,248 --> 00:06:53,212
Although this one is not using revalidation,

166
00:06:53,212 --> 00:06:57,073
but simply the default "dynamicParams" behavior.

167
00:06:57,073 --> 00:06:59,166
Now, since we're using a time

168
00:06:59,166 --> 00:07:01,042
interval for revalidation,

169
00:07:01,115 --> 00:07:03,836
the pages will always be regenerated

170
00:07:03,836 --> 00:07:06,325
if they're older than 30 seconds,

171
00:07:06,325 --> 00:07:08,521
no matter whether there is new

172
00:07:08,521 --> 00:07:10,205
data in the CMS or not.

173
00:07:10,278 --> 00:07:12,324
If I keep reloading this page,

174
00:07:12,324 --> 00:07:15,744
at some point the existing version will expire,

175
00:07:15,744 --> 00:07:18,171
and you can see in the server logs that

176
00:07:18,171 --> 00:07:20,451
the component was rendered again.

177
00:07:20,451 --> 00:07:23,947
Even though the data in the CMS hasn't changed,

178
00:07:23,947 --> 00:07:27,324
so the page will look the same as before anyway.

179
00:07:27,324 --> 00:07:30,344
But it still made a fetch request to Strapi,

180
00:07:30,344 --> 00:07:32,961
and regenerated the HTML.

181
00:07:32,961 --> 00:07:35,982
The Next.js app has no way of knowing

182
00:07:35,982 --> 00:07:39,396
if the data in the CMS has changed or not.

183
00:07:39,396 --> 00:07:41,239
After generating the page,

184
00:07:41,239 --> 00:07:45,093
the server will reuse it for at least 30 seconds,

185
00:07:45,093 --> 00:07:45,880
and so on.

186
00:07:45,958 --> 00:07:49,233
I'm saying "at least" 30 seconds because

187
00:07:49,233 --> 00:07:52,377
there isn't a timer that goes off automatically

188
00:07:52,377 --> 00:07:56,822
and regenerates the page after exactly 30 seconds.

189
00:07:56,822 --> 00:08:00,070
The process is driven by client requests.

190
00:08:00,070 --> 00:08:03,861
If nobody loads this page for say 3 hours,

191
00:08:03,861 --> 00:08:06,339
then the server will not regenerate

192
00:08:06,339 --> 00:08:07,897
it during that period.

193
00:08:07,968 --> 00:08:11,074
It's only when a client makes a request that

194
00:08:11,074 --> 00:08:13,379
the server will detect that the

195
00:08:13,379 --> 00:08:15,237
existing page is too old,

196
00:08:15,312 --> 00:08:18,096
and therefore needs to be rerendered.

197
00:08:18,096 --> 00:08:20,315
So, time-based revalidation

198
00:08:20,315 --> 00:08:22,205
is very easy to enable:

199
00:08:22,287 --> 00:08:25,793
you just need to export the "revalidate" property

200
00:08:25,793 --> 00:08:29,705
specifying a time interval in number of seconds.

201
00:08:29,705 --> 00:08:33,030
But it's important to understand how it works.

202
00:08:33,030 --> 00:08:35,123
It's effectively a cache.

203
00:08:35,123 --> 00:08:37,775
Each static page is cached,

204
00:08:37,775 --> 00:08:40,573
and expires after the given interval.

