Next.js Dynamic Routes (Sinhala): Route Parameters & Catch-all Tutorial

ආයුබෝවන් යාළුවනේ! වෙබ් Development ලෝකයේදී අපි හැමෝටම හුඟක් වෙලාවට හම්බවෙන දෙයක් තමයි Dynamic Content කියන්නේ. ඒ කියන්නේ හැම user කෙනාටම, හැම product එකකටම, හැම blog post එකකටම වෙනම URL එකක් හදන්න වෙන එක. හිතන්න, අපිට Blog Post දහස් ගාණක් තියෙනවා නම්, ඒ හැම එකටම වෙන වෙනම page එකක් හදන්න පුළුවන්ද? බැහැ නේද? එතකොට තමයි Next.js හි Dynamic Routes අපේ ගලවාගැනීමට එන්නේ!
මේ tutorial එකෙන් අපි Next.js වල Dynamic Routes කියන්නේ මොකක්ද, ඒවා කොහොමද හදන්නේ, ඒ වගේම ඊටත් වඩා flexible වෙන්න පුළුවන් Catch-all Routes මොනවද කියලා පැහැදිලිව ඉගෙන ගමු. අපි theory විතරක් නෙවෙයි, practical උදාහරණත් එක්ක කතා කරන නිසා ඔයාට මේ concept එක පැහැදිලිව තේරේවි. එහෙනම්, අපි පටන් ගමු!
Dynamic Routes යනු කුමක්ද?
සාමාන්යයෙන් වෙබ් අඩවියක පිටු වලට static URL තියෙනවා. උදාහරණයක් විදියට, /about
, /contact
, /products
වගේ. මේවා වෙනස් වෙන්නේ නැහැ. හැබැයි, අපේ වෙබ් අඩවියේ තියෙන තොරතුරු නිරන්තරයෙන් වෙනස් වෙනකොට, හෝ විශාල දත්ත ප්රමාණයක් පෙන්වන්න ඕන වුණාම, හැම data item එකකටම වෙනම static page එකක් හදන්න බැහැ. එතකොට තමයි Dynamic Routes වගේ concept එකක් අවශ්ය වෙන්නේ.
Dynamic Routes වලින් වෙන්නේ, එකම Next.js Page Component එකකින්, විවිධ URL patterns වලට අනුරූපව වෙනස් Content එකක් පෙන්වන්න පුළුවන් වෙන එකයි. Next.js මේ සඳහා []
(square brackets) භාවිතා කරනවා. මේකෙන් අපිට Route Parameter එකක් specify කරන්න පුළුවන්.
උදාහරණයක් විදියට:
pages/blog/[slug].js
- මේකෙන්/blog/my-first-post
,/blog/another-article
වගේ URL වලට match කරන්න පුළුවන්. මෙතනmy-first-post
හෝanother-article
කියන්නේslug
parameter එකේ value එකයි.pages/products/[id].js
- මේකෙන්/products/123
,/products/456
වගේ URL වලට match කරන්න පුළුවන්. මෙතන123
හෝ456
කියන්නේid
parameter එකේ value එකයි.
මේ Route Parameters අපිට Page Component එක ඇතුලෙන් useRouter
Hook එකෙන් ලබාගන්න පුළුවන්. ඒක හරියටම කොහොමද කරන්නේ කියලා අපි ඊළඟ section එකේදී බලමු.
Dynamic Routes ක්රියාත්මක කරමු (Implementing Dynamic Routes)
අපි හිතමු අපිට Blog එකක් හදන්න ඕනේ කියලා. ඒකේ හැම Post එකකටම වෙනම URL එකක් තියෙන්න ඕනේ. ඒකට Dynamic Route එකක් හදාගන්නේ මෙහෙමයි:
පියවර 1: Folder Structure එක හදමු
ඔයාගේ Next.js project එකේ pages
folder එක ඇතුලේ blog
කියලා folder එකක් හදන්න. ඊට පස්සේ ඒ blog
folder එක ඇතුලේ [slug].js
කියලා file එකක් හදන්න. මේ [slug].js
කියන එකෙන් තමයි අපි Dynamic Route එක define කරන්නේ.
# Project root එකේ ඉඳන්
mkdir pages/blog
touch pages/blog/[slug].js
පියවර 2: Page Component එක ලියමු
දැන් pages/blog/[slug].js
file එක ඇතුලේ මේ code එක ලියන්න:
import { useRouter } from 'next/router';
import Head from 'next/head';
export default function BlogPost() {
const router = useRouter();
const { slug } = router.query;
if (!router.isReady) {
return <div>Loading...</div>; // router එක ready වෙනකම් පොඩි Loading state එකක්
}
return (
<div>
<Head>
<title>Blog Post: {slug ? slug.replace(/-/g, ' ') : 'Loading...'} | My Blog</title>
</Head>
<h1>Welcome to Blog Post: {slug ? slug.replace(/-/g, ' ') : 'Not Found'}</h1>
<p>This is the content for the blog post titled <strong>{slug ? slug.replace(/-/g, ' ') : 'Loading...'}!</strong></p>
<p><a href="/">Go back home</a></p>
</div>
);
}
මේ code එකෙන් අපි කරන්නේ:
next/router
එකෙන්useRouter
Hook එක import කරගන්නවා.router.query
object එකෙන් අපේ Dynamic parameter එක (මේ උදාහරණයේslug
) ලබාගන්නවා.router.isReady
කියන එකෙන් router එකේ query parameters load වෙලාද කියලා බලනවා. SSR (Server-Side Rendering) හෝ SSG (Static Site Generation) භාවිතා කරන්නේ නැත්නම් මුලින්මrouter.query
එක empty වෙන්න පුළුවන්.- ලැබුණු
slug
එක Page එකේ Header එකේ සහ Content එකේ display කරනවා.slug.replace(/-/g, ' ')
කියන එකෙන් URL එකේ තියෙන hyphens (-
) spaces බවට පත් කරනවා, ඒක Post Title එකක් වගේ පෙන්වන්න පහසුයි.
දැන් ඔයාගේ Browser එකේ http://localhost:3000/blog/my-first-post
හෝ http://localhost:3000/blog/next-js-awesome
වගේ URL එකකට ගිහින් බලන්න. ඔයාට ඒ slug
එකට අදාළව Content එක display වෙනවා පෙනේවි.
Catch-all Routes තේරුම් ගනිමු (Understanding Catch-all Routes)
Dynamic Routes වලින් අපිට එක segment එකක් විතරයි match කරන්න පුළුවන් වුණේ. උදාහරණයක් විදියට, /blog/[slug]
කියන්නේ /blog/post-title
වගේ URL එකකට. හැබැයි අපිට /docs/getting-started/installation/windows
වගේ තව ගොඩක් segments තියෙන URL එකකට match කරන්න ඕන වුණොත් Dynamic Routes හරියන්නේ නැහැ. එතකොට තමයි Catch-all Routes අපිට උදව් වෙන්නේ.
Catch-all Routes නිර්මාණය කරන්නේ [...slug]
(square brackets ඇතුලේ dots තුනක් එක්ක parameter name එක) භාවිතා කරලයි. මේකෙන් වෙන්නේ, ඒ Route එකට අදාළව එන ඕනෑම URL segments ගණනක් එක parameter එකක් විදියට අරගෙන array එකක් විදියට අපිට ලබාදෙන එකයි.
උදාහරණයක් විදියට:
pages/docs/[...slug].js
වගේ Route එකක් තිබ්බොත්:/docs/getting-started
කියන URL එකට ගියොත්,slug
කියන එකේ value එක['getting-started']
කියලා array එකක් විදියට ලැබෙනවා./docs/getting-started/installation
කියන URL එකට ගියොත්,slug
කියන එකේ value එක['getting-started', 'installation']
කියලා array එකක් විදියට ලැබෙනවා./docs/getting-started/installation/windows
කියන URL එකට ගියොත්,slug
කියන එකේ value එක['getting-started', 'installation', 'windows']
කියලා array එකක් විදියට ලැබෙනවා.
මේක හරියටම "wildcard" route එකක් වගේ. Documentation site, file explorers වගේ hierarchical (ඉහල සිට පහලට තියෙන) content තියෙන තැන් වලට මේක හුඟක් ප්රයෝජනවත්.
Catch-all Routes ක්රියාත්මක කරමු (Implementing Catch-all Routes)
අපි හිතමු අපිට documentation site එකක් හදන්න ඕනේ කියලා. ඒකේ විවිධ sections සහ sub-sections තියෙනවා. ඒකට Catch-all Route එකක් හදාගන්නේ මෙහෙමයි:
පියවර 1: Folder Structure එක හදමු
pages
folder එක ඇතුලේ docs
කියලා folder එකක් හදන්න. ඊට පස්සේ ඒ docs
folder එක ඇතුලේ [...slug].js
කියලා file එකක් හදන්න.
# Project root එකේ ඉඳන්
mkdir pages/docs
touch pages/docs/[...slug].js
පියවර 2: Page Component එක ලියමු
දැන් pages/docs/[...slug].js
file එක ඇතුලේ මේ code එක ලියන්න:
import { useRouter } from 'next/router';
import Head from 'next/head';
export default function DocPage() {
const router = useRouter();
const { slug } = router.query;
if (!router.isReady) {
return <div>Loading...</div>;
}
const docPath = Array.isArray(slug) ? slug.join(' / ') : 'Home';
const title = Array.isArray(slug) && slug.length > 0
? slug[slug.length - 1].replace(/-/g, ' ')
: 'Documentation Home';
return (
<div>
<Head>
<title>{title} | Our Docs</title>
</Head>
<h1>Documentation for: {docPath}</h1>
<p>This page explains the topic of <strong>{title}</strong>.</p>
<p><a href="/">Go back home</a></p>
<p><a href="/docs">Go to Docs Home</a></p>
</div>
);
}
මේ code එකත් කලින් වගේමයි, හැබැයි මේ වතාවේ slug
කියන එක array එකක් විදියට ලැබෙන නිසා, අපි ඒක Array.isArray(slug)
කියලා check කරලා, join(' / ')
method එකෙන් readable string එකක් බවට පත් කරගන්නවා.
දැන් ඔයාගේ Browser එකේ http://localhost:3000/docs/getting-started
, http://localhost:3000/docs/installation/windows
, http://localhost:3000/docs/api-reference/v2/users
වගේ URL වලට ගිහින් බලන්න. ඔයාට පෙනේවි slug
array එකේ content එකට අදාළව page එක වෙනස් වෙන හැටි. /docs
කියලා ගියොත්, slug
එක undefined
වෙන්න පුළුවන්, ඒකටත් අපි Documentation Home
කියලා fallback එකක් දාලා තියෙනවා.
Optional Catch-all Routes:
තව දෙයක් තියෙනවා, අපිට /docs
කියන URL එකටත් match වෙන්න ඕන නම් (එතකොට slug
array එක හිස් වෙන්න ඕනේ) [[...slug]].js
කියලා file එක හදන්න පුළුවන්. ඒ කියන්නේ, brackets දෙකක් ඇතුලේ dots තුනක් එක්ක parameter name එක දාන එක. එතකොට /docs
සහ /docs/a/b
දෙකටම මේක match වෙනවා.
වැදගත් කරුණු සහ ගැටළු විසඳීම (Best Practices & Troubleshooting)
Dynamic Routes සහ Catch-all Routes හුඟක් ප්රයෝජනවත් වුණත්, ඒවා භාවිතා කරනකොට මතක තියාගන්න ඕන වැදගත් කරුණු කිහිපයක් තියෙනවා.
Route Matching Order (Route ගැලපෙන පිළිවෙල)
Next.js Routes match කරනකොට නිශ්චිත පිළිවෙලකට යනවා. මේක වැදගත්, මොකද routes අතර ගැටුම් ඇතිවෙන්න පුළුවන්:
- Specific Static Routes: මුලින්ම match වෙන්නේ නිශ්චිත static routes. උදා:
/blog/about.js
- Dynamic Routes: ඊට පස්සේ match වෙන්නේ
[slug]
වගේ Dynamic Routes. උදා:/blog/[slug].js
- Catch-all Routes: අන්තිමට match වෙන්නේ
[...slug]
වගේ Catch-all Routes. උදා:/blog/[...slug].js
මේ නිසා, ඔයාට /blog/about
කියන පිටුවට වෙනම Page එකක් ඕන නම්, pages/blog/about.js
කියලා file එකක් හදන්න. pages/blog/[slug].js
එකට කලින් ඒක match වෙනවා.
Potential Route Conflicts (Routes අතර ගැටුම්)
සමහර වෙලාවට Routes අතර ගැටුම් ඇතිවෙන්න පුළුවන්, විශේෂයෙන්ම එකම folder එකේ Dynamic සහ Catch-all Routes දෙකම තිබ්බොත්. උදාහරණයක් විදියට, pages/blog/[slug].js
සහ pages/blog/[...slug].js
දෙකම තියෙනවා නම්, /blog/my-post
කියන එක [slug]
එකට match වෙනවා. [...slug]
එකට ඒක match වෙන්නේ නැහැ. Catch-all Route එකකට reach වෙන්න නම්, ඊට වඩා specific route එකක් (static හෝ dynamic) නැති වෙන්න ඕනේ.
[[...slug]]
(optional catch-all) භාවිතා කරනකොට විශේෂයෙන්ම සැලකිලිමත් වෙන්න. /docs/index.js
වගේ static page එකක් එක්ක /docs/[[...slug]].js
තියෙනවා නම් /docs
කියන URL එකට index.js
එක match වෙනවා, [[...slug]].js
එක match වෙන්නේ නැහැ. මේක Next.js වල route resolution logic එකේ කොටසක්.
When to Use Catch-all Routes (Catch-all Routes භාවිතා කළ යුත්තේ කවදාද?)
Catch-all Routes හුඟක් powerful වුණත්, ඒවා භාවිතා කරන්න ඕනේ නිශ්චිත අවස්ථාවලදී විතරයි. සෑම Dynamic Route එකකටම Catch-all Route එකක් භාවිතා කිරීම සුදුසු නැහැ. Content එකේ hierarchy එකක් තියෙන documentation වගේ sites වලට, හෝ filesystem එකක් හරහා files serve කරනකොට වගේ තැන් වලට Catch-all Routes ඉතාම හොඳයි. Simple blog posts වලට [slug].js
වගේ Dynamic Route එකක් ඇති.
Error Handling (වැරදි හසුරුවන ආකාරය)
useRouter
එකෙන් ලබාගන්නා parameters undefined
වෙන්න පුළුවන්, විශේෂයෙන්ම client-side navigation වලදී router.isReady
false වෙන වෙලාවට. ඒ නිසා, code එක ලියනකොට මේ වගේ scenarios වලට if (!router.isReady) { return <div>Loading...</div>; }
වගේ check කිරීම් දාන්න පුරුදු වෙන්න.
Data Fetching (දත්ත ලබාගැනීම)
Dynamic Routes එක්ක වැඩ කරනකොට, ඒ Route Parameter එකට අදාළ දත්ත load කරන්න getStaticProps
, getStaticPaths
, හෝ getServerSideProps
වගේ Next.js Data Fetching methods භාවිතා කරන්න සිද්ධ වෙනවා. මේ methods වලින් Server-side එකේදී හෝ Build time එකේදී data fetch කරලා, ඒ parameter එකට අදාළව page එක generate කරලා User ට provide කරන්න පුළුවන්.
උදාහරණයක් විදියට getStaticPaths
භාවිතා කරලා ඔයාගේ blog posts වල සියලුම slugs list කරලා Build time එකේදී pages generate කරන්න පුළුවන්. getStaticProps
වලින් ඒ ඒ slug එකට අදාළ post data එක fetch කරන්න පුළුවන්.
නිගමනය (Conclusion)
Next.js හි Dynamic Routes සහ Catch-all Routes කියන්නේ නූතන වෙබ් යෙදුම් නිර්මාණය කිරීමේදී අත්යවශ්ය මෙවලම් දෙකක්. මේවා නිවැරදිව භාවිතා කිරීමෙන්, ඔයාට flexible, scalable සහ maintain කරන්න පහසු වෙබ් අඩවි හදන්න පුළුවන්. අපි මේ tutorial එකෙන් Dynamic Routes හදන හැටි, useRouter
එකෙන් parameters extract කරන හැටි, ඒ වගේම Catch-all Routes වල ප්රයෝජන සහ ඒවා භාවිතා කළ යුතු අවස්ථා ගැනත් ඉගෙනගත්තා.
දැන් ඔයාට මේ concept එක ගැන හොඳ අවබෝධයක් තියෙනවා ඇති කියලා මම හිතනවා. මතක තියාගන්න, theory දැනගෙන ඉන්නවට වඩා practice කිරීම තමයි වැදගත්ම දේ. ඒ නිසා, ඔයාගේ ඊළඟ Next.js project එකේදී මේ Routes අත්හදා බලන්න. Documentation site එකක් හදලා බලන්න, නැත්නම් blog එකක comments section එකක් Dynamic Routes වලින් develop කරලා බලන්න.
ඔබේ අදහස්, මේ ගැන තියෙන ප්රශ්න, හෝ මේ සම්බන්ධයෙන් ඔබේ අත්දැකීම් පහතින් Comment Section එකේ දාලා යන්න අමතක කරන්න එපා. අපි තවත් මේ වගේ වැදගත් tutorial එකකින් හමුවෙමු! ජය වේවා!