In the Quantum Metropolis, the most advanced transportation system possesses a remarkable ability to adapt to the needs of its citizens. Transport routes are not rigidly defined - they can dynamically reorganize to guide travelers to any location in the city. This flexibility is key to the efficient functioning of such a complex urban organism.
In the world of Next.js 15, dynamic path segments serve an analogous function, allowing you to create routes that adapt to different parameters and contexts. They are what make navigation in an application truly interactive and tailored to the user's needs.
In Next.js 15, dynamic path segments are created by placing the parameter name in square brackets
[param]. Such a folder will match different values in that URL segment, and the parameter value will be available inside the page components.Here is what the file structure looks like for an application with dynamic segments:
1app/
2 ├── destinations/
3 │ ├── page.tsx # matches /destinations
4 │ └── [planetId]/ # matches /destinations/:planetId (dynamic segment)
5 │ └── page.tsx # matches /destinations/mars, /destinations/venus, etc.In this example,
[planetId] is a dynamic segment that can accept any value, e.g., "mars", "venus", or "jupiter". This value is then available in the page component as params.planetId.Let's look at the implementation of a page that uses the dynamic segment
[planetId]:1// app/destinations/[planetId]/page.tsx
2import Image from 'next/image';
3import { notFound } from 'next/navigation';
4
5// This type defines the parameter structure for this page
6type PlanetPageParams = {
7 params: Promise<{
8 planetId: string;
9 }>;
10};
11
12async function getPlanetData(planetId: string) {
13 // Normally we would fetch data from an API or database here
14 // For this example, we use static data
15 const planets = {
16 'mars': {
17 name: 'Mars',
18 description: 'The Red Planet known for harsh conditions and fascinating geological phenomena.',
19 gravity: '3.721 m/s²',
20 diameter: '6,779 km',
21 dayLength: '24h 37m',
22 yearLength: '687 Earth days',
23 temperature: '-63°C (average)',
24 imageUrl: '/images/mars.jpg'
25 },
26 'venus': {
27 name: 'Venus',
28 description: 'The second planet from the Sun, known for its extremely hot climate and dense atmosphere.',
29 gravity: '8.87 m/s²',
30 diameter: '12,104 km',
31 dayLength: '243 Earth days',
32 yearLength: '225 Earth days',
33 temperature: '462°C (average)',
34 imageUrl: '/images/venus.jpg'
35 },
36 'jupiter': {
37 name: 'Jupiter',
38 description: 'The largest planet in the Solar System, known for the Great Red Spot and numerous moons.',
39 gravity: '24.79 m/s²',
40 diameter: '139,820 km',
41 dayLength: '9h 56m',
42 yearLength: '11.86 Earth years',
43 temperature: '-108°C (average)',
44 imageUrl: '/images/jupiter.jpg'
45 }
46 };
47
48 return planets[planetId];
49}
50
51// Component receives params as props
52export default async function PlanetPage({ params }: PlanetPageParams) {
53 // Fetching planet data based on planetId
54 const planet = await getPlanetData((await params).planetId);
55
56 // If the planet doesn't exist, show the 404 page
57 if (!planet) {
58 notFound();
59 }
60
61 return (
62 <div className="container mx-auto px-4 py-12">
63 <h1 className="text-4xl font-bold mb-8">{planet.name}</h1>
64
65 <div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
66 <div className="relative h-96 lg:h-auto rounded-lg overflow-hidden">
67 <Image
68 src={planet.imageUrl}
69 alt={planet.name}
70 fill
71 className="object-cover"
72 priority
73 />
74 </div>
75
76 <div className="space-y-6">
77 <p className="text-lg text-gray-700">{planet.description}</p>
78
79 <div className="bg-gray-50 p-6 rounded-lg shadow-sm">
80 <h2 className="text-2xl font-semibold mb-4">Planetary Data</h2>
81 <table className="w-full">
82 <tbody>
83 <tr className="border-b">
84 <th className="text-left py-2">Gravity</th>
85 <td className="text-right py-2">{planet.gravity}</td>
86 </tr>
87 <tr className="border-b">
88 <th className="text-left py-2">Diameter</th>
89 <td className="text-right py-2">{planet.diameter}</td>
90 </tr>
91 <tr className="border-b">
92 <th className="text-left py-2">Day Length</th>
93 <td className="text-right py-2">{planet.dayLength}</td>
94 </tr>
95 <tr className="border-b">
96 <th className="text-left py-2">Year Length</th>
97 <td className="text-right py-2">{planet.yearLength}</td>
98 </tr>
99 <tr>
100 <th className="text-left py-2">Temperature</th>
101 <td className="text-right py-2">{planet.temperature}</td>
102 </tr>
103 </tbody>
104 </table>
105 </div>
106
107 <div className="flex space-x-4">
108 <a
109 href={`/destinations/\${(await params).planetId}/colonies\`}
110 className="px-6 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors"
111 >
112 Colonies
113 </a>
114 <a
115 href={`/destinations/\${(await params).planetId}/tours\`}
116 className="px-6 py-3 border border-indigo-600 text-indigo-600 rounded-lg hover:bg-indigo-50 transition-colors"
117 >
118 Tours
119 </a>
120 </div>
121 </div>
122 </div>
123 </div>
124 );
125}In the code above:
PlanetPageParams type, which specifies the parameter structure received by the componentPlanetPage component receives a params object containing planetId from the URLplanetId to fetch data about the planetIf we know in advance all possible values for a dynamic segment, we can generate static pages during the build process, which significantly improves performance. The
generateStaticParams function serves this purpose:1// app/destinations/[planetId]/page.tsx
2
3// This function defines the static paths that will be generated during the build
4export async function generateStaticParams() {
5 // Normally we would fetch data from an API or database here
6 // We return an array of objects with parameters to be statically generated
7 return [
8 { planetId: 'mars' },
9 { planetId: 'venus' },
10 { planetId: 'jupiter' }
11 ];
12}
13
14// Rest of the component...Thanks to this, Next.js will generate three static pages during the build: for Mars, Venus, and Jupiter. This will significantly speed up their loading, as they won't need to be dynamically generated with each request.
In the Quantum Metropolis, the transportation system enables traveling to any destination through a series of precise transfers, each narrowing the space to the selected target. Similarly in Next.js 15, we can create multi-level dynamic segments to precisely specify the requested resources.
1app/
2 ├── destinations/
3 │ ├── [planetId]/ # matches /destinations/:planetId
4 │ │ ├── page.tsx # matches /destinations/mars
5 │ │ └── [moonId]/ # matches /destinations/:planetId/:moonId
6 │ │ └── page.tsx # matches /destinations/mars/phobos
7 │ └── page.tsx # matches /destinationsIn this structure, we have two levels of dynamic segments:
[planetId] - planet identifier[moonId] - moon identifier for the given planet1// app/destinations/[planetId]/[moonId]/page.tsx
2import Image from 'next/image';
3import Link from 'next/link';
4import { notFound } from 'next/navigation';
5
6type MoonPageParams = {
7 params: Promise<{
8 planetId: string;
9 moonId: string;
10 }>;
11};
12
13async function getMoonData(planetId: string, moonId: string) {
14 // Moon-to-planet mapping system
15 const moonData = {
16 'mars': {
17 'phobos': {
18 name: 'Phobos',
19 description: 'The larger and closer of Mars's two natural satellites, orbiting the planet every 7 hours and 39 minutes.',
20 diameter: '22.2 km',
21 orbitDistance: '9,376 km',
22 discovered: '1877',
23 imageUrl: '/images/phobos.jpg'
24 },
25 'deimos': {
26 name: 'Deimos',
27 description: 'The smaller and farther of Mars's two natural satellites, with an irregular shape.',
28 diameter: '12.6 km',
29 orbitDistance: '23,463 km',
30 discovered: '1877',
31 imageUrl: '/images/deimos.jpg'
32 }
33 },
34 'jupiter': {
35 'europa': {
36 name: 'Europa',
37 description: 'Jupiter's moon that may harbor a subsurface ocean of water beneath its icy crust.',
38 diameter: '3,121.6 km',
39 orbitDistance: '670,900 km',
40 discovered: '1610',
41 imageUrl: '/images/europa.jpg'
42 },
43 'io': {
44 name: 'Io',
45 description: 'The most volcanically active object in the Solar System, with over 400 active volcanoes.',
46 diameter: '3,643.2 km',
47 orbitDistance: '421,700 km',
48 discovered: '1610',
49 imageUrl: '/images/io.jpg'
50 },
51 'ganymede': {
52 name: 'Ganymede',
53 description: 'The largest moon in the Solar System, even larger than the planet Mercury.',
54 diameter: '5,268.2 km',
55 orbitDistance: '1,070,400 km',
56 discovered: '1610',
57 imageUrl: '/images/ganymede.jpg'
58 }
59 }
60 };
61
62 // Check if the planet and moon exist
63 if (!moonData[planetId] || !moonData[planetId][moonId]) {
64 return null;
65 }
66
67 return {
68 ...moonData[planetId][moonId],
69 planet: planetId
70 };
71}
72
73export default async function MoonPage({ params }: MoonPageParams) {
74 const { planetId, moonId } = await params;
75 const moon = await getMoonData(planetId, moonId);
76
77 if (!moon) {
78 notFound();
79 }
80
81 return (
82 <div className="container mx-auto px-4 py-12">
83 <div className="flex items-center mb-8">
84 <Link
85 href={`/destinations/\${planetId}\`}
86 className="text-indigo-600 hover:underline flex items-center"
87 >
88 <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
89 <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
90 </svg>
91 Back to {planetId.charAt(0).toUpperCase() + planetId.slice(1)}
92 </Link>
93 </div>
94
95 <h1 className="text-4xl font-bold mb-8">{moon.name}</h1>
96
97 <div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
98 <div className="relative h-96 lg:h-auto rounded-lg overflow-hidden">
99 <Image
100 src={moon.imageUrl}
101 alt={moon.name}
102 fill
103 className="object-cover"
104 priority
105 />
106 </div>
107
108 <div className="space-y-6">
109 <p className="text-lg text-gray-700">{moon.description}</p>
110
111 <div className="bg-gray-50 p-6 rounded-lg shadow-sm">
112 <h2 className="text-2xl font-semibold mb-4">Information</h2>
113 <table className="w-full">
114 <tbody>
115 <tr className="border-b">
116 <th className="text-left py-2">Planet</th>
117 <td className="text-right py-2">{moon.planet.charAt(0).toUpperCase() + moon.planet.slice(1)}</td>
118 </tr>
119 <tr className="border-b">
120 <th className="text-left py-2">Diameter</th>
121 <td className="text-right py-2">{moon.diameter}</td>
122 </tr>
123 <tr className="border-b">
124 <th className="text-left py-2">Orbit Distance</th>
125 <td className="text-right py-2">{moon.orbitDistance}</td>
126 </tr>
127 <tr>
128 <th className="text-left py-2">Discovered</th>
129 <td className="text-right py-2">{moon.discovered}</td>
130 </tr>
131 </tbody>
132 </table>
133 </div>
134
135 <div className="flex space-x-4">
136 <a
137 href={`/destinations/\${planetId}/\${moonId}/research\`}
138 className="px-6 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors"
139 >
140 Scientific Research
141 </a>
142 <a
143 href={`/destinations/\${planetId}/\${moonId}/landing-sites\`}
144 className="px-6 py-3 border border-indigo-600 text-indigo-600 rounded-lg hover:bg-indigo-50 transition-colors"
145 >
146 Landing Sites
147 </a>
148 </div>
149 </div>
150 </div>
151 </div>
152 );
153}
154
155export async function generateStaticParams() {
156 // We generate all possible combinations of planets and their moons
157 return [
158 { planetId: 'mars', moonId: 'phobos' },
159 { planetId: 'mars', moonId: 'deimos' },
160 { planetId: 'jupiter', moonId: 'europa' },
161 { planetId: 'jupiter', moonId: 'io' },
162 { planetId: 'jupiter', moonId: 'ganymede' }
163 ];
164}In this example:
planetId and moonIdIn the Quantum Metropolis, some transport lines are so flexible that they can reach any number of points along the route, collecting all relevant route data as travel parameters. In Next.js 15, the equivalents are catch-all and optional catch-all segments.
A catch-all segment, denoted as
[...param], matches a path with any number of segments. All matched segments are passed as an array.1app/
2 ├── stellar-objects/
3 │ ├── [...path]/ # matches /stellar-objects/any/number/of/segments
4 │ │ └── page.tsx
5 │ └── page.tsx # matches /stellar-objectsImplementation of a page with a catch-all segment:
1// app/stellar-objects/[...path]/page.tsx
2type CatchAllParams = {
3 params: Promise<{
4 path: string[];
5 }>;
6};
7
8export default async function StellarObjectsPage({ params }: CatchAllParams) {
9 const { path } = await params;
10
11 return (
12 <div className="container mx-auto px-4 py-12">
13 <h1 className="text-4xl font-bold mb-8">Stellar Objects Browser</h1>
14
15 <div className="bg-gray-100 p-4 rounded mb-8">
16 <p className="font-mono">Path: /{path.join('/')}</p>
17 <p>Segments: {path.length}</p>
18 <ul className="list-disc pl-6 mt-2">
19 {path.map((segment, index) => (
20 <li key={index}>Segment {index + 1}: {segment}</li>
21 ))}
22 </ul>
23 </div>
24
25 {/* Normal page content here... */}
26 </div>
27 );
28}Example URL:
/stellar-objects/stars/main-sequence/g-type will be matched to this page, and params.path will be the array ["stars", "main-sequence", "g-type"].An optional catch-all segment, denoted as
[[...param]] (double square brackets), works similarly to the standard catch-all, but also matches the path without any additional segments.1app/
2 ├── knowledge-base/
3 ├── [[...topic]]/ # matches /knowledge-base, /knowledge-base/planets, /knowledge-base/planets/terrestrial, etc.
4 └── page.tsxImplementation:
1// app/knowledge-base/[[...topic]]/page.tsx
2type OptionalCatchAllParams = {
3 params: Promise<{
4 topic?: string[];
5 }>;
6};
7
8export default async function KnowledgeBasePage({ params }: OptionalCatchAllParams) {
9 const { topic } = await params;
10
11 // If topic doesn't exist, we're on the main knowledge base page
12 const isRoot = !topic || topic.length === 0;
13
14 return (
15 <div className="container mx-auto px-4 py-12">
16 <h1 className="text-4xl font-bold mb-8">
17 {isRoot ? 'Space Knowledge Base' : 'Topic: ' + topic.join(' > ')}
18 </h1>
19
20 {isRoot ? (
21 <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
22 <TopicCard title="Planets" href="/knowledge-base/planets" />
23 <TopicCard title="Stars" href="/knowledge-base/stars" />
24 <TopicCard title="Galaxies" href="/knowledge-base/galaxies" />
25 {/* More topic cards... */}
26 </div>
27 ) : (
28 <div>
29 <div className="bg-gray-100 p-4 rounded mb-8">
30 <p>You are browsing topic: <strong>{topic.join(' > ')}</strong></p>
31
32 <div className="mt-4">
33 <a href="/knowledge-base" className="text-indigo-600 hover:underline">
34 Return to the main knowledge base page
35 </a>
36 </div>
37 </div>
38
39 {/* Specific topic content... */}
40 </div>
41 )}
42 </div>
43 );
44}
45
46function TopicCard({ title, href }) {
47 return (
48 <a href={href} className="block p-6 bg-white rounded-lg shadow-md hover:shadow-lg transition-shadow">
49 <h2 className="text-xl font-semibold mb-2">{title}</h2>
50 <p className="text-gray-600">Discover knowledge about {title.toLowerCase()}.</p>
51 </a>
52 );
53}This page will match both
/knowledge-base (main knowledge base page) and /knowledge-base/planets/terrestrial (specific topic).In the Quantum Metropolis, not only citizen transport lines use route parameters - automated systems also communicate with each other through dynamically configured channels. In Next.js 15, the equivalent is Route Handlers, which can also use dynamic segments.
1app/
2 ├── api/
3 ├── planets/
4 ├── [id]/
5 │ └── route.ts # matches /api/planets/:id
6 └── route.ts # matches /api/planetsImplementation of a Route Handler with a dynamic segment:
1// app/api/planets/[id]/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3
4// Type for parameters
5type PlanetRouteContext = {
6 params: Promise<{
7 id: string;
8 }>;
9};
10
11// Sample data
12const planetData = {
13 'mars': {
14 id: 'mars',
15 name: 'Mars',
16 type: 'terrestrial',
17 habitable: false
18 },
19 'earth': {
20 id: 'earth',
21 name: 'Earth',
22 type: 'terrestrial',
23 habitable: true
24 },
25 'jupiter': {
26 id: 'jupiter',
27 name: 'Jupiter',
28 type: 'gas-giant',
29 habitable: false
30 }
31};
32
33export async function GET(
34 request: NextRequest,
35 { params }: PlanetRouteContext
36) {
37 const { id } = await params;
38
39 // Check if the planet exists
40 if (!planetData[id]) {
41 return NextResponse.json(
42 { error: 'Planet not found' },
43 { status: 404 }
44 );
45 }
46
47 // Return planet data
48 return NextResponse.json(planetData[id]);
49}
50
51export async function PUT(
52 request: NextRequest,
53 { params }: PlanetRouteContext
54) {
55 const { id } = await params;
56
57 // Check if the planet exists
58 if (!planetData[id]) {
59 return NextResponse.json(
60 { error: 'Planet not found' },
61 { status: 404 }
62 );
63 }
64
65 try {
66 // Parse data from the request
67 const updateData = await request.json();
68
69 // Update planet data (simulation only)
70 // In a real application, we would save this to a database
71 const updatedPlanet = {
72 ...planetData[id],
73 ...updateData
74 };
75
76 // Return the updated data
77 return NextResponse.json(updatedPlanet);
78 } catch (error) {
79 return NextResponse.json(
80 { error: 'Invalid data' },
81 { status: 400 }
82 );
83 }
84}
85
86export async function DELETE(
87 request: NextRequest,
88 { params }: PlanetRouteContext
89) {
90 const { id } = await params;
91
92 // Check if the planet exists
93 if (!planetData[id]) {
94 return NextResponse.json(
95 { error: 'Planet not found' },
96 { status: 404 }
97 );
98 }
99
100 // Delete the planet (simulation only)
101 // In a real application, we would delete it from the database
102
103 return NextResponse.json({ success: true });
104}In this example:
idid parameter is available through the params object passed to the handler functionsIn the Quantum Metropolis, beyond the main routes, the transportation system can be additionally configured through optional parameters such as "expressFlight" or "comfortLevel". In the world of Next.js, these optional settings are represented by query parameters.
1// app/search/page.tsx
2import { Suspense } from 'react';
3
4// This is a server component
5export default async function SearchPage({
6 searchParams
7}: {
8 searchParams: Promise<{ [key: string]: string | string[] | undefined }>
9}) {
10 // Get query parameters
11 const query = (await searchParams).q || '';
12 const category = (await searchParams).category || 'all';
13 const page = Number((await searchParams).page) || 1;
14
15 return (
16 <div className="container mx-auto px-4 py-12">
17 <h1 className="text-4xl font-bold mb-8">Space Search Engine</h1>
18
19 <div className="mb-8">
20 <p>Search: <strong>{query}</strong></p>
21 <p>Category: <strong>{category}</strong></p>
22 <p>Page: <strong>{page}</strong></p>
23 </div>
24
25 <Suspense fallback={<div>Loading results...</div>}>
26 <SearchResults query={query} category={category} page={page} />
27 </Suspense>
28 </div>
29 );
30}
31
32// This component fetches and displays results
33async function SearchResults({
34 query,
35 category,
36 page
37}: {
38 query: string | string[],
39 category: string | string[],
40 page: number
41}) {
42 // Normally we would fetch data based on the parameters
43 // Simulating delay for Suspense demonstration
44 await new Promise(resolve => setTimeout(resolve, 1000));
45
46 // If there's no query, display a message
47 if (!query) {
48 return (
49 <div className="bg-gray-100 p-8 rounded-lg text-center">
50 <p className="text-lg">Enter a phrase to start searching.</p>
51 </div>
52 );
53 }
54
55 // Normally we would display search results here
56 return (
57 <div className="space-y-6">
58 <div className="p-6 bg-white rounded-lg shadow">
59 <h2 className="text-xl font-semibold mb-2">Result 1</h2>
60 <p>Found for: {query}</p>
61 </div>
62 <div className="p-6 bg-white rounded-lg shadow">
63 <h2 className="text-xl font-semibold mb-2">Result 2</h2>
64 <p>Found for: {query}</p>
65 </div>
66 <div className="p-6 bg-white rounded-lg shadow">
67 <h2 className="text-xl font-semibold mb-2">Result 3</h2>
68 <p>Found for: {query}</p>
69 </div>
70
71 <div className="flex justify-center space-x-2 mt-8">
72 <a
73 href={`/search?q=\${query}&category=\${category}&page=\${Math.max(1, page - 1)}\`}
74 className={`px-4 py-2 border rounded \${page === 1 ? 'text-gray-400 cursor-not-allowed' : 'text-indigo-600 hover:bg-indigo-50'}\`}
75 >
76 Previous
77 </a>
78 <span className="px-4 py-2 bg-indigo-600 text-white rounded">
79 {page}
80 </span>
81 <a
82 href={`/search?q=\${query}&category=\${category}&page=\${page + 1}\`}
83 className={`px-4 py-2 border rounded \${page === 1 ? 'text-gray-400 cursor-not-allowed' : 'text-indigo-600 hover:bg-indigo-50'}\`}
84 >
85 Next
86 </a>
87 </div>
88 </div>
89 );
90}In this example:
SearchPage component receives searchParams as props, containing all query parameters from the URLSearchResults component, which fetches data based on the parametersSuspense to handle the loading state1// app/api/search/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3
4export async function GET(request: NextRequest) {
5 // Get URL from the request
6 const { searchParams } = new URL(request.url);
7
8 // Get query parameters
9 const query = searchParams.get('q');
10 const category = searchParams.get('category') || 'all';
11 const page = Number(searchParams.get('page')) || 1;
12 const limit = Number(searchParams.get('limit')) || 10;
13
14 // Check if query exists
15 if (!query) {
16 return NextResponse.json(
17 { error: 'The q (query) parameter is required' },
18 { status: 400 }
19 );
20 }
21
22 // Here we would normally fetch data from a database
23 // For the sake of this example, we return simulated data
24 const results = Array.from({ length: limit }, (_, i) => ({
25 id: `result-\${(page - 1) * limit + i + 1}`,
26 title: `Wynik \${(page - 1) * limit + i + 1} dla "\${query}"`,
27 category,
28 relevance: Math.round(Math.random() * 100)
29 }));
30
31 return NextResponse.json({
32 query,
33 category,
34 page,
35 limit,
36 totalResults: 100, // Simulated total number of results
37 results
38 });
39}In this example:
new URL(request.url).searchParams to get query parametersIn the Quantum Metropolis, every transport line has dynamically generated route information available through the city's information system. In Next.js 15, we can generate dynamic metadata for each page using the
generateMetadata function.1// app/destinations/[planetId]/page.tsx
2import { Metadata } from 'next';
3
4// Type for parameters
5type PlanetParams = {
6 params: Promise<{
7 planetId: string;
8 }>;
9};
10
11// Function generating metadata based on planetId
12export async function generateMetadata(
13 { params }: PlanetParams
14): Promise<Metadata> {
15 const { planetId } = await params;
16
17 // Fetching planet data
18 const planet = await getPlanetData(planetId);
19
20 // If the planet doesn't exist, return default metadata
21 if (!planet) {
22 return {
23 title: 'Planet not found | Quantum Voyages',
24 description: 'No information found about the requested planet.'
25 };
26 }
27
28 // Return planet-specific metadata
29 return {
30 title: `\${planet.name} | Quantum Voyages`,
31 description: planet.description.substring(0, 160), // Limit to 160 characters for SEO
32 openGraph: {
33 title: `Odkryj \${planet.name} z Quantum Voyages`,
34 description: planet.description.substring(0, 160),
35 images: [
36 {
37 url: `https://example.com\${planet.imageUrl}`,
38 width: 1200,
39 height: 630,
40 alt: planet.name
41 }
42 ]
43 }
44 };
45}
46
47// Rest of the component code...In this example:
generateMetadata receives the same params as the page componentplanetId to fetch planet dataDynamic path segments and parameters in Next.js 15 are powerful tools that enable the creation of flexible and interactive applications. Just as in the Quantum Metropolis, where the transportation system adapts to the needs of its citizens, dynamic routing in Next.js adapts to user needs.
Key points to remember:
[param]params prop[...param]) allow matching multiple path segments[[...param]]) work similarly but also match the path without additional segmentssearchParams prop in page componentsWith these features, you can build advanced applications with intuitive navigation and rich functionality tailored to specific user needs.
In the next chapter, we'll discover how to efficiently navigate between different pages in our application using the
Link component and the useRouter hook.