All language subtitles for 009 Static Generation for Dynamic Routes_en

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian Download
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 1 00:00:03,000 --> 00:00:05,423 The ReviewsPage now automatically 2 00:00:05,423 --> 00:00:07,038 lists all the reviews. 3 00:00:07,112 --> 00:00:11,185 And each individual ReviewPage is a dynamic route, 4 00:00:11,185 --> 00:00:14,384 so whenever we write a new Markdown file, 5 00:00:14,384 --> 00:00:17,393 a new page will be available automatically 6 00:00:17,393 --> 00:00:18,682 for the same path. 7 00:00:18,753 --> 00:00:22,101 But so far we only tested this dynamic 8 00:00:22,101 --> 00:00:24,215 route in the dev server. 9 00:00:24,303 --> 00:00:26,557 Let's add a log statement here, 10 00:00:26,783 --> 00:00:28,702 printing a message every time 11 00:00:28,702 --> 00:00:30,489 this component is rendered. 12 00:00:30,555 --> 00:00:32,887 And let's log the "slug" as well, 13 00:00:32,887 --> 00:00:36,576 so we can tell exactly which route was generated. 14 00:00:36,576 --> 00:00:39,336 Now, we know that the dev server 15 00:00:39,336 --> 00:00:42,962 always re-renders each page at every request. 16 00:00:42,962 --> 00:00:45,215 But what will happen in production? 17 00:00:45,215 --> 00:00:48,206 Let's stop the server, and see our how 18 00:00:48,206 --> 00:00:50,883 dynamic route works in production. 19 00:00:50,962 --> 00:00:53,591 First of all, we need to build our app, 20 00:00:53,882 --> 00:00:57,112 to create an optimized production build. 21 00:00:57,112 --> 00:00:59,804 The build output itself is quite interesting. 22 00:00:59,804 --> 00:01:02,287 If you notice, "/reviews/[slug]" 23 00:01:02,287 --> 00:01:04,691 has a lambda symbol next to it, 24 00:01:04,769 --> 00:01:07,434 not a circle like the other pages. 25 00:01:07,434 --> 00:01:09,806 At the bottom, it explains that 26 00:01:09,806 --> 00:01:11,566 the "lambda" means that 27 00:01:11,642 --> 00:01:15,603 that route "server-side renders at runtime". 28 00:01:15,603 --> 00:01:19,416 So, it's not a static page, like the other ones. 29 00:01:19,416 --> 00:01:21,709 Let's see what this means in practice, 30 00:01:21,709 --> 00:01:24,137 if we start the production server. 31 00:01:24,137 --> 00:01:25,908 Let's reload this page. 32 00:01:26,397 --> 00:01:29,179 You can see that the server rendered 33 00:01:29,179 --> 00:01:30,957 the ReviewPage 3 times: 34 00:01:31,034 --> 00:01:33,469 once for every different slug. 35 00:01:33,469 --> 00:01:36,212 Now, that's because of prefetching. 36 00:01:36,212 --> 00:01:38,489 We opened the Reviews page, 37 00:01:38,489 --> 00:01:42,028 that contains links to those three other pages, 38 00:01:42,028 --> 00:01:45,126 so the browser prefetched all the links. 39 00:01:45,126 --> 00:01:47,481 But what's more interesting thing is that 40 00:01:47,481 --> 00:01:51,177 the server rendered each page at runtime. 41 00:01:51,177 --> 00:01:53,098 This will be clearer if we look 42 00:01:53,098 --> 00:01:54,585 at an individual review. 43 00:01:54,647 --> 00:01:57,322 There's nothing new in the server logs, 44 00:01:57,322 --> 00:01:59,660 because this page had already been 45 00:01:59,660 --> 00:02:01,449 prefetched by the browser. 46 00:02:01,517 --> 00:02:03,918 But if we reload the same page, 47 00:02:03,918 --> 00:02:06,694 you can see that the server re-rendered 48 00:02:06,694 --> 00:02:08,261 the "hellblade" route. 49 00:02:08,332 --> 00:02:10,737 And every time we click reload, 50 00:02:10,737 --> 00:02:13,953 the server will re-render this page again. 51 00:02:13,953 --> 00:02:17,669 Every time the browser requests this URL path 52 00:02:17,669 --> 00:02:20,170 the server runs our component code 53 00:02:20,170 --> 00:02:24,253 and regenerates the HTML sent to the browser. 54 00:02:24,253 --> 00:02:28,284 So, this is what server-side rendering means. 55 00:02:28,284 --> 00:02:31,379 It basically works like the dev server, 56 00:02:31,379 --> 00:02:33,754 with the difference that, in production, 57 00:02:33,754 --> 00:02:36,401 it also prefetches all the links. 58 00:02:36,401 --> 00:02:39,801 But with this approach we lose the benefits 59 00:02:39,801 --> 00:02:42,174 of statically generated pages. 60 00:02:42,253 --> 00:02:45,064 Returning a static page is faster, 61 00:02:45,064 --> 00:02:48,126 because the HTML file was generated 62 00:02:48,126 --> 00:02:49,613 during the build, 63 00:02:49,700 --> 00:02:52,812 there's no need to render it at runtime. 64 00:02:52,812 --> 00:02:56,083 And also, server-side rendering requires 65 00:02:56,083 --> 00:02:58,127 running a Node.js server. 66 00:02:58,209 --> 00:03:00,957 It's not compatible with doing 67 00:03:00,957 --> 00:03:02,881 a static HTML export. 68 00:03:02,973 --> 00:03:07,066 So, is there any way to generate static pages, 69 00:03:07,066 --> 00:03:09,811 even when using a dynamic route? 70 00:03:09,811 --> 00:03:11,747 It is in fact possible. 71 00:03:11,747 --> 00:03:13,836 But we need to tell Next.js 72 00:03:13,836 --> 00:03:15,769 which routes to generate. 73 00:03:15,846 --> 00:03:19,451 Because "/reviews/[slug]" is just a pattern; 74 00:03:19,451 --> 00:03:21,921 it will match any path named 75 00:03:21,921 --> 00:03:23,862 "/reviews/" something. 76 00:03:23,950 --> 00:03:26,365 To generate some static pages 77 00:03:26,365 --> 00:03:28,446 Next.js will need to know 78 00:03:28,530 --> 00:03:31,131 exactly which "slugs" are available. 79 00:03:31,131 --> 00:03:33,633 We can provide that information 80 00:03:33,633 --> 00:03:36,054 by exporting an async function 81 00:03:36,135 --> 00:03:39,026 called "generateStaticParams". 82 00:03:39,835 --> 00:03:42,343 And here we need to return an array, 83 00:03:42,343 --> 00:03:45,149 specifying which routes are valid. 84 00:03:45,149 --> 00:03:48,433 Each element in this array must be an object, 85 00:03:48,433 --> 00:03:51,332 containing the params that will be passed 86 00:03:51,332 --> 00:03:53,312 to the ReviewPage component. 87 00:03:53,383 --> 00:03:56,518 Since this route has a "slug" parameter 88 00:03:56,518 --> 00:03:59,574 that's what we need to put inside this object. 89 00:03:59,574 --> 00:04:02,881 For example, we have a review for "hellblade". 90 00:04:02,881 --> 00:04:05,595 Then we can add another similar object, 91 00:04:05,595 --> 00:04:07,840 this time for "hollow-knight". 92 00:04:08,195 --> 00:04:11,178 Let's just return these two for the moment, 93 00:04:11,178 --> 00:04:12,961 and see what happens now, 94 00:04:13,258 --> 00:04:15,677 if we build our app for production. 95 00:04:17,418 --> 00:04:19,629 You can see that our dynamic route 96 00:04:19,629 --> 00:04:21,189 was treated differently. 97 00:04:21,254 --> 00:04:24,031 Under the "/reviews/[slug]" pattern 98 00:04:24,031 --> 00:04:26,673 there are now two specific paths: 99 00:04:26,673 --> 00:04:29,259 "hellblade", and "hollow-knight". 100 00:04:29,259 --> 00:04:32,806 Those are, of course, the two slugs we returned 101 00:04:32,806 --> 00:04:35,901 from our "generateStaticParams" function. 102 00:04:35,976 --> 00:04:38,600 Also, this route is now marked 103 00:04:38,600 --> 00:04:40,436 with a filled circle. 104 00:04:40,524 --> 00:04:43,149 At the bottom, it explains that 105 00:04:43,149 --> 00:04:45,605 that symbol stands for "SSG", 106 00:04:45,690 --> 00:04:48,670 which means "Static Site Generation". 107 00:04:48,670 --> 00:04:51,447 Now, this legend shows SSG as 108 00:04:51,447 --> 00:04:53,745 different from "Static", 109 00:04:53,841 --> 00:04:55,322 but, in practice, they're 110 00:04:55,322 --> 00:04:56,802 basically the same thing. 111 00:04:56,861 --> 00:04:59,352 SSG is also static. 112 00:04:59,352 --> 00:05:01,147 You may also notice that 113 00:05:01,147 --> 00:05:04,451 our ReviewPage was rendered during the build, 114 00:05:04,451 --> 00:05:07,244 with different values for each slug. 115 00:05:07,244 --> 00:05:09,485 This didn't happen before we 116 00:05:09,485 --> 00:05:11,647 added generateStaticParams. 117 00:05:11,727 --> 00:05:14,696 So this is how we can get Next.js 118 00:05:14,696 --> 00:05:16,945 to generate static pages, 119 00:05:17,035 --> 00:05:19,827 even when using a dynamic route. 120 00:05:19,827 --> 00:05:22,484 But we don't really want to hard-code 121 00:05:22,484 --> 00:05:24,832 all the possible slug values 122 00:05:24,832 --> 00:05:26,845 in generateStaticParams. 123 00:05:26,929 --> 00:05:28,875 We already have a "getReviews" 124 00:05:28,875 --> 00:05:30,692 function in this other file, 125 00:05:30,757 --> 00:05:33,512 that we could call to get all the reviews. 126 00:05:33,512 --> 00:05:37,204 However, this code reads each Markdown file, 127 00:05:37,204 --> 00:05:41,083 to load all the properties, like title and body. 128 00:05:41,083 --> 00:05:43,493 While in generateStaticParams 129 00:05:43,493 --> 00:05:45,404 we only need the slugs. 130 00:05:45,487 --> 00:05:49,065 So, to avoid reading many files unnecessarily, 131 00:05:49,065 --> 00:05:51,117 let's write a separate function, 132 00:05:51,885 --> 00:05:53,640 called "getSlugs". 133 00:05:54,225 --> 00:05:56,700 And here we can use the same code 134 00:05:56,700 --> 00:05:58,500 we wrote for getReviews, 135 00:05:58,575 --> 00:06:02,007 that lists all the files in the "content" folder, 136 00:06:02,007 --> 00:06:05,349 and extracts the "slugs" from the file names. 137 00:06:05,349 --> 00:06:09,300 We can simply return the slugs directly from here. 138 00:06:09,300 --> 00:06:11,371 Now, to avoid duplication, we 139 00:06:11,371 --> 00:06:13,228 can also replace this code 140 00:06:13,299 --> 00:06:16,553 with a call to our new "getSlugs" function, 141 00:06:16,553 --> 00:06:19,577 and the rest will work in the same way. 142 00:06:19,577 --> 00:06:21,915 We basically just moved some code 143 00:06:21,915 --> 00:06:23,756 into a different function. 144 00:06:23,827 --> 00:06:27,078 But this way, in "generateStaticParams", 145 00:06:27,078 --> 00:06:28,755 we can get all the "slugs" 146 00:06:28,818 --> 00:06:31,142 by awaiting the Promise returned 147 00:06:31,142 --> 00:06:32,595 by our new function. 148 00:06:32,668 --> 00:06:36,317 generateStaticParams is already async. 149 00:06:36,317 --> 00:06:38,690 Now, here we need to return an 150 00:06:38,690 --> 00:06:40,668 array like the one below, 151 00:06:40,747 --> 00:06:42,988 where each element is an object 152 00:06:42,988 --> 00:06:44,650 with a "slug" property. 153 00:06:44,723 --> 00:06:48,253 But this "slugs" variable is an array of strings. 154 00:06:48,253 --> 00:06:52,282 So we need to use "map" to transform each string 155 00:06:52,282 --> 00:06:55,472 into an object with the "slug" as a property. 156 00:06:55,472 --> 00:06:57,560 Note that we need parentheses 157 00:06:57,560 --> 00:06:59,432 around the object literal, 158 00:06:59,504 --> 00:07:02,476 otherwise JavaScript will treat the curly 159 00:07:02,476 --> 00:07:04,651 brackets as the function body. 160 00:07:04,724 --> 00:07:08,331 Anyway, we can now delete this hard-coded array, 161 00:07:08,331 --> 00:07:09,492 save this file, 162 00:07:09,492 --> 00:07:11,398 and go and build our app again, 163 00:07:11,398 --> 00:07:14,734 to see if our code works as intended. 164 00:07:15,618 --> 00:07:17,728 You can see that the dynamic route 165 00:07:17,728 --> 00:07:21,544 now resulted in three statically generated pages, 166 00:07:21,544 --> 00:07:23,638 one for each available review. 167 00:07:23,638 --> 00:07:25,330 That's what we wanted! 168 00:07:25,330 --> 00:07:27,483 Let's start the production server, 169 00:07:27,483 --> 00:07:30,400 and see how our application works now. 170 00:07:30,400 --> 00:07:32,832 If we reload the Reviews page, 171 00:07:32,832 --> 00:07:35,398 there's nothing in the server logs. 172 00:07:35,398 --> 00:07:38,178 And if we open the Hellblade review, 173 00:07:38,178 --> 00:07:41,104 even if we try reloading it a few times, 174 00:07:41,104 --> 00:07:44,604 again the server never renders any component. 175 00:07:44,604 --> 00:07:48,068 Because all the pages have been statically 176 00:07:48,068 --> 00:07:50,048 generated at build time. 177 00:07:50,130 --> 00:07:54,138 So, to recap: we can write a generateStaticParams 178 00:07:54,138 --> 00:07:54,792 function 179 00:07:54,874 --> 00:07:57,406 returning all the possible paths, 180 00:07:57,406 --> 00:08:00,118 and Next.js will generate static 181 00:08:00,118 --> 00:08:02,745 pages even for a dynamic route. 13237

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.