I really like this approach, using Suspense with a data-fetching server component; it's simple, and it works. Good alternative to something fancy like parallel intercepting routes.
I think you'll be better off with using parallel routes since you can render parts like a modal independent of the main page that you're on. In the video each time a modal is opened, the get products fetch also gets called, and you don't want to fetch products every time you open a new modal. In case of parallel routes, the modal would just show up because it's not being rendered by the products page, and the products page would remain the way it is without rerendering.
@@alexambrinos That's true, but there's plenty of times you don't want your modals to be accessible outside of some context, and still navigable. This particular case could go either way IMO. Also, I'm not sure that there actually are new fetches going on when you press the links because each link should be treated as a new route that is pre-fetched and stored in the route cache. This means that Suspense only triggers on the first render.
This works great. Thanks for the work you put in! I changed the modal so it can have child components, using it for different use cases like adding users. Thanks Taylor!
Great tutorial mate. I'm playing around with intercepting & parallel routes to open a product preview, but.. when linking to that product from elsewhere in the app it always opens the preview (modal). any ideas ?
Few more questions. After implementing it this way I noticed that my page in the background did a rerender when the searchParams changed, even if I did router.replace instead of pushing the params. Also I wonder what are the pros of doing it this way (besides the js bundle size difference of a single client/server component), instead of just toggling the modal with a provider and passing in the server components by prop? I'd assume a modal would be the ideal usecase for keeping the modal a client component and passing in the server components? I'm asking because I'm not entirely sure.
You could try using window.history.replaceState as this replaces the URL without browser refresh. The main benefit I think is SEO - pretty sure the search engines can pick up the URLs for each product modal when they're server rendered, but not with client components because it uses JavaScript to render the modal.
@@taylorlindoresreeves Thanks. Doesn't seem like you can "wait" executing/fetching from a server component child component until the parent modal client component is opened. It seem as if the modal is a client component, and ServerComponentThatFetches is passed as child/prop it starts fetching its data immediately and does not wait for the modal to show its content. So server modals might be our only option if we have serer components inside the modal that needs to fetch some data upon display.
Around thee 4.10 mark you mention that it's a bit of a technical challenge but definitely still doable to implement server side modals for global modals, but I'm curious how you'd do that let's say for a modal you trigger from clicking a button/icon in a global header, since you have no way of knowing whether search params changed from the root layout? :-)
You can achieve this using middleware to capture the search parameters, storing them in a cookie. This same cookie can then be accessed in the layout at load time and during server‑side rendering.
@@taylorlindoresreeves don't you mean setting them in a header and not a cookie? Just like you do for the pathname? That will opt all routes into dynamic rendering, but that might be acceptable.
I do like this approach and in fact I have used this for search, filter, etc on production. But it is a pain to set up because you always have to handle cases where user type in random strings in the browser address bar and if you don't have an error page or redirect set up your api will return nothing or throw. For instance in your case if user enters a product id that don't exist, the fetch is still being called and you are gonna get an error because product dont exist.
Yeah this is a pain! You could always set up a global mechanism for preventing this using middleware by checking search parameters against the database (if it’s edge compatible) and redirecting if it does not exist. But as you can imagine this brings with it a load on database. Indexes could help with preventing db performance issues.
@@taylorlindoresreeves Thanks for the tip, that is actually a good shout. Also glad to know I am not alone in hating to make skeletons, espeicially ones that work well on stretchy container on all viewport sizes :P
Very helpful. Respected sir, i am unable to organise folder and components structure specially dealing with API. In a component there is a tab change option i mean like tab all, jobs, news. So when click tab then respected tab need to show different ui. Now in this same component layout also need to fetch data from api but I want to keep fetch Api in server component for better performance and improve seo. Since tab need to handle click event so component need to be client right. Can you please guide how can I arrange so that API data fetch from server component and at the same time tab change option work. Thank you
You would need to move the server action or fetch() higher up in the component tree so that it is in a server component, then you can pass the data down into the tabs. You could use searchParams (URL state) in the server component to filter depending on what data is required.
I really like this approach, using Suspense with a data-fetching server component; it's simple, and it works. Good alternative to something fancy like parallel intercepting routes.
Glad you like it!
I think you'll be better off with using parallel routes since you can render parts like a modal independent of the main page that you're on. In the video each time a modal is opened, the get products fetch also gets called, and you don't want to fetch products every time you open a new modal. In case of parallel routes, the modal would just show up because it's not being rendered by the products page, and the products page would remain the way it is without rerendering.
@@alexambrinos this makes sense. Are there any examples online of this? Could you please share some resources 🙏
@@alexambrinos That's true, but there's plenty of times you don't want your modals to be accessible outside of some context, and still navigable. This particular case could go either way IMO. Also, I'm not sure that there actually are new fetches going on when you press the links because each link should be treated as a new route that is pre-fetched and stored in the route cache. This means that Suspense only triggers on the first render.
you channel is really underrated.I hope that you keep posting this tricks with us.Waiting for your next video
This a real gem content.👌 Hoping for more nextjs video. Thank you so much.❤
More to come!
This works great. Thanks for the work you put in! I changed the modal so it can have child components, using it for different use cases like adding users. Thanks Taylor!
Thanks for watching, glad you got it working 👍
Nice tutorial! Good explanations and balanced between explanation and writing code. Looking forward to more videos!
Thank you, more to come!
Excellent video! keep em coming, cheers
Thanks, will do!
Thank you for the video . Keep going bro !
Thanks man!
very useful video, keep up the great work
Great tutorial mate. I'm playing around with intercepting & parallel routes to open a product preview, but.. when linking to that product from elsewhere in the app it always opens the preview (modal). any ideas ?
Few more questions. After implementing it this way I noticed that my page in the background did a rerender when the searchParams changed, even if I did router.replace instead of pushing the params. Also I wonder what are the pros of doing it this way (besides the js bundle size difference of a single client/server component), instead of just toggling the modal with a provider and passing in the server components by prop? I'd assume a modal would be the ideal usecase for keeping the modal a client component and passing in the server components? I'm asking because I'm not entirely sure.
You could try using window.history.replaceState as this replaces the URL without browser refresh. The main benefit I think is SEO - pretty sure the search engines can pick up the URLs for each product modal when they're server rendered, but not with client components because it uses JavaScript to render the modal.
@@taylorlindoresreeves Thanks. Doesn't seem like you can "wait" executing/fetching from a server component child component until the parent modal client component is opened. It seem as if the modal is a client component, and ServerComponentThatFetches is passed as child/prop it starts fetching its data immediately and does not wait for the modal to show its content. So server modals might be our only option if we have serer components inside the modal that needs to fetch some data upon display.
Around thee 4.10 mark you mention that it's a bit of a technical challenge but definitely still doable to implement server side modals for global modals, but I'm curious how you'd do that let's say for a modal you trigger from clicking a button/icon in a global header, since you have no way of knowing whether search params changed from the root layout? :-)
You can achieve this using middleware to capture the search parameters, storing them in a cookie. This same cookie can then be accessed in the layout at load time and during server‑side rendering.
@@taylorlindoresreeves don't you mean setting them in a header and not a cookie? Just like you do for the pathname? That will opt all routes into dynamic rendering, but that might be acceptable.
i would love to see nxtjs14, using something like state managment for full app
Is this similar to interceptingRoutes somehow? Under the hood looks similar 🤔
I do like this approach and in fact I have used this for search, filter, etc on production. But it is a pain to set up because you always have to handle cases where user type in random strings in the browser address bar and if you don't have an error page or redirect set up your api will return nothing or throw. For instance in your case if user enters a product id that don't exist, the fetch is still being called and you are gonna get an error because product dont exist.
Yeah this is a pain! You could always set up a global mechanism for preventing this using middleware by checking search parameters against the database (if it’s edge compatible) and redirecting if it does not exist. But as you can imagine this brings with it a load on database. Indexes could help with preventing db performance issues.
@@taylorlindoresreeves Thanks for the tip, that is actually a good shout. Also glad to know I am not alone in hating to make skeletons, espeicially ones that work well on stretchy container on all viewport sizes :P
Thx a lot!
dud, u ar amezing!! thks
Thanks for watching 🙏
your contents explains a lot of things that we have to know. thank you so much and i would love to see much more videos
This server sided thingy is out of hand. What next ,server sided client browser
Please Zoom in your editor more.
Please increase font size , You are doing awesome but 😢
Cool Video, but the font size kinda small
Thanks for the feedback. I’ll make sure it’s zoomed in much more in future videos 🙏
very clever way to show a modal 100% with server components.
Very helpful. Respected sir, i am unable to organise folder and components structure specially dealing with API.
In a component there is a tab change option i mean like tab all, jobs, news. So when click tab then respected tab need to show different ui. Now in this same component layout also need to fetch data from api but I want to keep fetch Api in server component for better performance and improve seo. Since tab need to handle click event so component need to be client right. Can you please guide how can I arrange so that API data fetch from server component and at the same time tab change option work. Thank you
You would need to move the server action or fetch() higher up in the component tree so that it is in a server component, then you can pass the data down into the tabs. You could use searchParams (URL state) in the server component to filter depending on what data is required.
very useful, keep it up buddy