1
00:00:03,000 --> 00:00:04,583
At this stage our app

2
00:00:04,583 --> 00:00:06,618
can display our First Post,

3
00:00:07,193 --> 00:00:10,001
loading the content form a Markdown file.

4
00:00:10,501 --> 00:00:12,327
Now, what if we want to add

5
00:00:12,327 --> 00:00:13,544
another blog post?

6
00:00:14,167 --> 00:00:16,729
We could create another Markdown file,

7
00:00:16,729 --> 00:00:18,346
let's say "second-post".

8
00:00:18,914 --> 00:00:20,435
And let's change the "date",

9
00:00:21,114 --> 00:00:23,192
the "title" to say "Second",

10
00:00:23,192 --> 00:00:24,750
and same in the body.

11
00:00:26,614 --> 00:00:27,699
We can remove the rest

12
00:00:27,699 --> 00:00:28,537
for this example.

13
00:00:29,679 --> 00:00:31,955
Now, how do we display the data

14
00:00:31,955 --> 00:00:33,789
in the new Markdown file?

15
00:00:33,789 --> 00:00:36,285
We could create another page here,

16
00:00:36,285 --> 00:00:38,340
but it would be very similar

17
00:00:38,340 --> 00:00:40,615
to this existing FirstPostPage.

18
00:00:41,408 --> 00:00:43,571
Almost all the code in this page

19
00:00:43,571 --> 00:00:45,395
would stay exactly the same

20
00:00:45,395 --> 00:00:47,624
when displaying a different post.

21
00:00:48,259 --> 00:00:51,041
The only thing that needs to change is

22
00:00:51,041 --> 00:00:53,311
the value we pass to "getPost",

23
00:00:53,311 --> 00:00:55,800
that specifies which file to load.

24
00:00:56,446 --> 00:00:59,510
So it would be nice to be able to reuse

25
00:00:59,510 --> 00:01:02,653
the code in this page for all the posts.

26
00:01:03,231 --> 00:01:05,802
We can easily rename this component

27
00:01:05,802 --> 00:01:07,345
to simply "PostPage",

28
00:01:07,345 --> 00:01:09,402
rather than "FirstPostPage".

29
00:01:12,064 --> 00:01:13,991
And our app will still work fine,

30
00:01:13,991 --> 00:01:15,917
because the name of our component

31
00:01:15,917 --> 00:01:17,201
doesn't really matter,

32
00:01:17,201 --> 00:01:19,244
as long as it's the default export.

33
00:01:19,920 --> 00:01:21,725
But as it is this page

34
00:01:21,725 --> 00:01:24,679
will still be visible only under the

35
00:01:24,679 --> 00:01:26,157
"first-post" path,

36
00:01:26,157 --> 00:01:29,193
because as we know the Next.js router

37
00:01:29,193 --> 00:01:32,558
exposes each page based on its file name.

38
00:01:32,558 --> 00:01:35,348
What if we want the same component

39
00:01:35,348 --> 00:01:39,041
to be used for multiple pages under "/posts",

40
00:01:39,041 --> 00:01:41,503
like a sort of wildcard match?

41
00:01:42,578 --> 00:01:45,930
Next.js allows us to define "dynamic routes",

42
00:01:45,930 --> 00:01:48,686
by naming this page in a special way.

43
00:01:49,260 --> 00:01:50,783
We can write square brackets,

44
00:01:51,283 --> 00:01:54,752
and inside that the name of the path parameter,

45
00:01:54,752 --> 00:01:56,155
for example "slug".

46
00:01:56,728 --> 00:01:59,578
This is a strange name for a file,

47
00:01:59,578 --> 00:02:02,259
but it's perfectly legal to have

48
00:02:02,259 --> 00:02:04,857
square brackets in a file name.

49
00:02:04,857 --> 00:02:07,120
So the idea is that any URL

50
00:02:07,120 --> 00:02:10,053
that starts with "posts/" something

51
00:02:10,053 --> 00:02:12,986
will match our "posts/[slug]" page.

52
00:02:13,905 --> 00:02:15,813
But we need to do something else

53
00:02:15,813 --> 00:02:16,887
before this works.

54
00:02:17,447 --> 00:02:19,864
We now get an error that says

55
00:02:19,864 --> 00:02:22,197
"getStaticPaths is required"

56
00:02:22,197 --> 00:02:24,198
"for dynamic SSG pages".

57
00:02:24,865 --> 00:02:28,392
So we need to add a "getStaticPaths" function

58
00:02:28,392 --> 00:02:29,332
to our code.

59
00:02:30,131 --> 00:02:33,097
This is similar to "getStaticProps",

60
00:02:33,097 --> 00:02:36,393
in that it must be exported and "async".

61
00:02:36,393 --> 00:02:39,030
But the purpose of this function

62
00:02:39,030 --> 00:02:42,327
is to tell Next.js which paths are valid

63
00:02:42,327 --> 00:02:44,222
for this dynamic route.

64
00:02:45,051 --> 00:02:46,452
Let's implement this function,

65
00:02:46,452 --> 00:02:47,713
and you'll see what I mean.

66
00:02:48,584 --> 00:02:50,657
This function returns an object

67
00:02:50,657 --> 00:02:52,663
that contains a "paths" array.

68
00:02:53,229 --> 00:02:56,379
And each item in this array is an object

69
00:02:56,379 --> 00:02:59,529
that in turn contains a "params" object,

70
00:02:59,529 --> 00:03:01,812
with parameters that identify

71
00:03:01,812 --> 00:03:03,387
this specific route.

72
00:03:04,123 --> 00:03:06,701
For example, in our case we want to set

73
00:03:06,701 --> 00:03:08,420
a parameter called "slug",

74
00:03:08,420 --> 00:03:10,138
because that's what we put

75
00:03:10,138 --> 00:03:12,782
inside square brackets in the file name.

76
00:03:13,480 --> 00:03:16,299
Now, we know that our existing page

77
00:03:16,299 --> 00:03:19,278
was visible under "posts/first-post",

78
00:03:19,278 --> 00:03:22,660
so we can set "slug" to "first-post" here.

79
00:03:23,322 --> 00:03:25,984
We're basically telling Next.js

80
00:03:25,984 --> 00:03:29,678
that "first-post" is one of the valid paths

81
00:03:29,678 --> 00:03:31,138
for our PostPage.

82
00:03:31,810 --> 00:03:34,462
But now we can add more paths,

83
00:03:34,462 --> 00:03:37,733
for example add a "second-post" here.

84
00:03:37,733 --> 00:03:40,473
So this way Next.js knowns that

85
00:03:40,473 --> 00:03:44,009
"posts/second-post" is also a valid URL.

86
00:03:44,775 --> 00:03:48,014
Now, the object returned by "getStaticPaths"

87
00:03:48,014 --> 00:03:50,885
must also include a "fallback" property

88
00:03:51,459 --> 00:03:54,889
that in our case we want to set to "false".

89
00:03:54,889 --> 00:03:57,680
The "fallback" option tells Next.js

90
00:03:57,680 --> 00:04:00,632
what to do if none of the paths above

91
00:04:00,632 --> 00:04:02,706
matches the requested URL.

92
00:04:02,706 --> 00:04:05,418
Setting it to false means no match

93
00:04:05,418 --> 00:04:08,290
will result in a 404 Not Found page,

94
00:04:08,290 --> 00:04:11,082
which is what we want in this case.

95
00:04:11,082 --> 00:04:12,757
Next.js also provides

96
00:04:12,757 --> 00:04:14,910
some more advanced features

97
00:04:14,910 --> 00:04:17,224
where if a page doesn't exist

98
00:04:17,224 --> 00:04:19,935
you can try building it on demand.

99
00:04:21,233 --> 00:04:23,674
But in that case your website will

100
00:04:23,674 --> 00:04:25,541
no longer be fully static.

101
00:04:26,112 --> 00:04:29,245
Now, the path we set in "getStaticPaths"

102
00:04:29,245 --> 00:04:32,220
will be available in "getStaticProps".

103
00:04:32,798 --> 00:04:34,765
This function receives an argument

104
00:04:34,765 --> 00:04:35,749
called "context".

105
00:04:36,306 --> 00:04:38,520
Let's start by logging that "context"

106
00:04:38,520 --> 00:04:40,793
so we'll see exactly what it contains.

107
00:04:41,352 --> 00:04:43,595
Now, let me show the browser window again,

108
00:04:45,818 --> 00:04:47,223
and also the server logs.

109
00:04:47,723 --> 00:04:49,160
Let's reload the page,

110
00:04:49,160 --> 00:04:50,793
and see what gets logged.

111
00:04:50,793 --> 00:04:53,275
Here's the call to "getStaticProps()",

112
00:04:53,905 --> 00:04:55,673
and the "context" object

113
00:04:55,673 --> 00:04:57,294
contains some "params"

114
00:04:57,294 --> 00:04:59,945
with the "slug" set to "first-post",

115
00:05:00,592 --> 00:05:03,171
Let's go through what happened step by step

116
00:05:03,171 --> 00:05:05,749
to make sure we understand what's going on.

117
00:05:06,308 --> 00:05:08,295
In the browser we requested

118
00:05:08,295 --> 00:05:10,282
the "posts/first-post" URL.

119
00:05:10,855 --> 00:05:13,748
The Next.js server received the request

120
00:05:14,248 --> 00:05:17,349
and matched it to our "[slug]" page,

121
00:05:17,349 --> 00:05:20,537
because it's under the "posts" folder

122
00:05:20,537 --> 00:05:22,604
and it's a dynamic route

123
00:05:22,604 --> 00:05:24,585
so it matches anything.

124
00:05:25,343 --> 00:05:27,797
But for this particular request

125
00:05:27,797 --> 00:05:31,280
the "slug" parameter is set to "first-post".

126
00:05:31,860 --> 00:05:33,672
Then Next.js executes

127
00:05:33,672 --> 00:05:36,175
our "getStaticPaths" function

128
00:05:36,175 --> 00:05:39,195
to check if "first-post" is in fact

129
00:05:39,195 --> 00:05:41,526
a valid path for this page.

130
00:05:42,285 --> 00:05:44,265
And it finds that it matches

131
00:05:44,265 --> 00:05:46,811
the first item in our "paths" array,

132
00:05:47,382 --> 00:05:50,288
so "first-post" is a valid request,

133
00:05:50,288 --> 00:05:52,529
and Next.js goes on to call

134
00:05:53,112 --> 00:05:55,294
the "getStaticProps" function,

135
00:05:55,294 --> 00:05:57,112
passing the matching path

136
00:05:57,112 --> 00:05:58,348
in the "context".

137
00:05:58,994 --> 00:06:01,364
In "getStaticProps" we then load

138
00:06:01,364 --> 00:06:04,106
the post data from the Markdown file,

139
00:06:04,106 --> 00:06:06,254
which is then passed as props

140
00:06:06,254 --> 00:06:08,699
to the component render function,

141
00:06:08,699 --> 00:06:10,996
that renders the HTML as usual.

142
00:06:11,793 --> 00:06:14,114
Now, what happens if we request

143
00:06:14,114 --> 00:06:15,762
"second-post" instead?

144
00:06:16,336 --> 00:06:18,773
The page still says "First Post",

145
00:06:18,773 --> 00:06:21,504
but that's just because at the moment

146
00:06:21,504 --> 00:06:24,310
we always load the same Markdown file.

147
00:06:24,957 --> 00:06:26,896
If we look at the server logs however,

148
00:06:27,757 --> 00:06:29,709
we can see that this time

149
00:06:29,709 --> 00:06:31,816
"getStaticProps" was called

150
00:06:31,816 --> 00:06:35,171
with "second-post" as the "slug" parameter.

151
00:06:35,827 --> 00:06:37,535
So we should make use of

152
00:06:37,535 --> 00:06:39,030
that "slug" parameter

153
00:06:39,030 --> 00:06:41,307
in our "getStaticProps" function

154
00:06:41,307 --> 00:06:43,869
to load the data for the right post.

155
00:06:44,582 --> 00:06:47,120
Let's destructure this "context" object

156
00:06:47,620 --> 00:06:49,325
and extract the "params".

157
00:06:49,825 --> 00:06:52,498
In fact we could even go one level deeper

158
00:06:52,498 --> 00:06:54,975
and get the "slug" directly from here.

159
00:06:55,825 --> 00:06:58,059
And now, instead of always loading

160
00:06:58,059 --> 00:06:59,505
the "first-post" data,

161
00:07:00,070 --> 00:07:02,166
we can pass the "slug" here.

162
00:07:02,166 --> 00:07:03,962
This should work because

163
00:07:03,962 --> 00:07:05,982
we named our Markdown files

164
00:07:05,982 --> 00:07:08,452
in the same way as our URL paths.

165
00:07:09,176 --> 00:07:10,985
So if we save this change,

166
00:07:10,985 --> 00:07:12,863
we can immediately see that

167
00:07:12,863 --> 00:07:15,645
the page now shows the Second Post data,

168
00:07:15,645 --> 00:07:18,427
so it's loading the right Markdown file.

169
00:07:19,135 --> 00:07:21,949
Let's make sure everything else still works.

170
00:07:21,949 --> 00:07:24,123
If we start from the "First Post",

171
00:07:24,123 --> 00:07:26,362
that still shows the right content.

172
00:07:26,989 --> 00:07:29,164
And if we request the "second-post",

173
00:07:29,164 --> 00:07:31,217
we need to enter the path manually

174
00:07:31,217 --> 00:07:33,754
because we haven't added a link to it yet,

175
00:07:34,374 --> 00:07:36,383
of course that also works fine.

176
00:07:36,883 --> 00:07:39,503
So that's how dynamic routes work

177
00:07:39,503 --> 00:07:40,376
in Next.js.

178
00:07:40,376 --> 00:07:43,076
There are a few moving parts here:

179
00:07:43,076 --> 00:07:45,378
we need to name the page file

180
00:07:45,378 --> 00:07:48,474
with this special square bracket syntax

181
00:07:48,474 --> 00:07:51,967
to match any request under the "posts" path,

182
00:07:51,967 --> 00:07:54,587
write a "getStaticPaths" function

183
00:07:54,587 --> 00:07:57,841
that says which paths are actually valid,

184
00:07:57,841 --> 00:08:00,382
and then use the "params" passed

185
00:08:00,382 --> 00:08:03,240
in the "context" to "getStaticProps"

186
00:08:03,240 --> 00:08:05,066
to load the right data.

