מה עושים במקום URL Params באפליקציית צד לקוח עם Next.js
הבאג הזה ב Next עורר דיון סוער:
https://github.com/vercel/next.js/discussions/64660
בקצרה כשאני בונה אפליקציית צד-לקוח בלבד עם output: 'export'
ב next.js אי אפשר להשתמש בנתיבים דינמיים, כלומר נתיב כזה לא יעבוד:
/blog/[slug]
ההסבר הוא שכשנקסט רואה כזה דבר הוא לא יודע איזה קובץ HTML לבנות, כי צריך לזכור שכל מנגנון הניתוב של נקסט באפליקציית צד לקוח בנוי על זה שהוא מריץ את קבצי הקומפוננטות לפי מערכת הקבצים ומייצר מערכת קבצי HTML מקבילה לקבצי ה JavaScript, כלומר מרנדר את כל קבצי ה page.tsx ושומר את התוצאות בתור HTML-ים.
ואם נשים בצד את כל הפיתרונות המתוחכמים ואת כל התקוות שבקרוב החברים ב Vercel יפתרו את זה (הם הבטיחו פיתרון באזור מאי-יוני), אבל כבר בינתיים אפשר לבנות פיתרון מקביל ודי פשוט - במקום להשתמש ב Route Params נשתמש ב Search Params, כלומר הנתיב יהיה:
/blog/post?slug=hello-world
בקוד next קצת נודניק ובשביל לגשת ל Search Params אני צריך לעטוף את הקומפוננטה ב Suspense לכן מבחינת קוד ב page.tsx אני כותב:
'use client'
import ShowPost from './show-post';
import { Suspense } from 'react';
export default function BlogPost() {
return (
<div>
<Suspense fallback={<p>Loading post</p>}>
<ShowPost />
</Suspense>
</div>
)
}
וב show-post.tsx יש לי:
'use client'
import Link from 'next/link';
import { getPost } from '@/lib/blog';
import { useSearchParams, notFound } from 'next/navigation';
export default function BlogPost() {
const slug = useSearchParams().get('slug')!;
const post = getPost(slug);
if (!post) {
return <p>Not flund. slug = {slug}</p>
}
return (
<div>
<h1>{post.title}</h1>
<p><Link href="/blog">Back to blog</Link></p>
<p>{post.fulltext}</p>
</div>
)
}
ובהנחה שאתם יודעים איך לקבל פוסט לפי slug הקוד יעבוד ויש לכם בלוג בתור אפליקציית עמוד יחיד.