Next.js Discord

Discord Forum

Generation of URL from nested routes and filters

Unanswered
Dunker posted this in #help-forum
Open in Discord

70 Replies

Avatar
DunkerOP
I want to build this URL in my next app
But my problem is, i have one home page, and everything happens in it
I don't want any navigation
Avatar
Mwskwong
There are two types of dynamic stuff in the Walmart example.
1. Params, i.e. electronics, all-laptops-computers, etc.
2. Search params, i.e. povid, facet, etc.


If you only have 1 listing page, most of the time you will only use (2) only
The /electronics/all-laptops-computer you listed there is more like a sub-listing page. i.e. a dedicated listing page for laptops ONLY.
Avatar
DunkerOP
I opened Walmart, picked things and it gave me
Just URL changed not pages
Hope you got me
Avatar
DunkerOP
Yep
First i am picking electronics, then laptops, then filters
I know its routing based on picks i am okay for it
I know how to build that routes, it's okay also
My problem is, when I pick electronics, i only want to see electronics from DB
Avatar
Mwskwong
By the change of "page", we usually refer to the change of /a/b/c part of the URL, without caring about the part after ?.
So selecting electronics and then laptops are changing page, just that

1. Those pages are using the "template" so they appear 90% the same
2. The navigation can be "fake", i.e. it is not doing a full page reload

But in theory, those are still considered as page change
Avatar
DunkerOP
Then I filter it like laptops, my db query will be electronic.laptops
My problem with sending requests to DB based on that URLs
Just this
Also thanks for your interest
I ll try to write some template code
Avatar
Mwskwong
Then you need to have a page like
// app/[category]/page.tsx
const ProductListingPage = async ({ params }) => {
  const products = await db.getProductsByCategory(params.category)
}
Avatar
DunkerOP
async Electronics
    await fetch(api/electronics)
Avatar
Mwskwong
You are NOT going to have a dedicated Electronics page, since that exact same page will be used by all sorts of different categories.
That's what I mean by "template"
Avatar
DunkerOP
Cuz my backend is not next
I got it
Did you get my issue
Avatar
Mwskwong
I don't. The db.getProductsByCategory(params.category) part can be fetching your BE of your own choice. It doesnt matter
Avatar
DunkerOP
Yep
But problem starts there
At next page, under in tree
Subroute
In category page:
fetch(/params.category
Its okay
Now I want to add filters in same page
To fetch filtered data from db
facet=processor_type%3AIntel+Core+i5%7C%7Cscreen_size_laptop%3A16%22+%26+Up&sort=price_low
My problem is here
I listed products based on category as dynamic.
But now when I pick some filters from page, i want to query db based on that filters
@Plott Hound was saying things about URL search object
At last situation, i want to see specific data based on my selection
But all of my URL params coming from my backend all have relations
Avatar
Mwskwong
Yes, that's the "search param" part.
const ProductListingPage = async ({ params, searchParams }) => {
  const products = await db.getProductsByCategory(params.category, { filterBy: searcParams })
}

Now let's say it's laptops. Then searchParams will mostly contain:

{
  cpu: 'i7',
  minRam: '16' // in GB,
  ...
}

FE's URL: /laptop?cpu=i7&minRam=16

And the backend should have the ability to handle these and that depends on how your BE expects those info to be passed in
Avatar
DunkerOP
/a/:id/b/:id/c/id?filter=filter1&filter2=filter2
My orm has include
And where
Like a.where(a => a.id == id).include(b => b.id) ...
How can I send that Fe URL to backend in fetch
With dynamic search params
Cuz search params not coming from a form
All that filters will come from frontend, users picks
Avatar
Plott Hound
Sorry I’m back at work but will look over this on my break
Avatar
DunkerOP
Okay thanks for help
Imagine like we're in deepest route in tree like a/1/b/2c/3/page.tsx
Avatar
Mwskwong
You are not supposed to just send the entire /laptops?cpu=i7&minRamn=16 URL to BE and think it will magically work.
You have access to params and searchParams now. You need to based on the requirement of the BE API, map the fields to the format of how BE expects those to be
/a/:aId/b/:bId/c/:cId?filter=filter1&filter2=filter2

// /app/a/[aId]/b/[bId]/c/[cId]/page.tsx
const DeeplyNestedPage = ({
  params: { aId, bId, cId },
  searchParams: { filter1, filter2 }
}) => {
  // do your stuff
}
Read the doc...
Avatar
DunkerOP
/a/:aId/b/:bId/c/:cId?filter=filter1&filter2=filter2

// /app/a/[aId]/b/[bId]/c/[cId]/page.tsx
const DeeplyNestedPage = ({
  params: { aId, bId, cId },
  searchParams: { filter1, filter2 }
}) => {
  fetch(a/aId/b/bId?filter=filter1...)
}
I don't want this
I want fetch data at every route based on params and search params
lets look at this example
// app/artist/[username]/page.tsx
import Albums from './albums'
 
async function getArtist(username: string) {
  const res = await fetch(`https://api.example.com/artist/${username}`)
  return res.json()
}
 
async function getArtistAlbums(username: string) {
  const res = await fetch(`https://api.example.com/artist/${username}/albums`)
  return res.json()
}
 
export default async function Page({
  params: { username },
}: {
  params: { username: string }
}) {
  // Initiate both requests in parallel
  const artistData = getArtist(username)
  const albumsData = getArtistAlbums(username)
 
  // Wait for the promises to resolve
  const [artist, albums] = await Promise.all([artistData, albumsData])
 
  return (
    <>
      <h1>{artist.name}</h1>
      <Albums list={albums}></Albums>
    </>
  )
}
yep, this tells my issue
my user flow is like this:
1. user picks a category /category/[cat]
 - fetch gives data based on category fetch(/category/cat

2. user picks a product /category/cat0/product/[prod]
 - fetch gives data based on that category and product fetch(/category/cat/product/prod

3. user picks a comment of product /category/cat0/product/prod0/comments
 - fetch gives data based on that category and product and comment fetch(/category/cat/prod/prod/comments

4. user filters comments based on its picks .../comments?f1=f1&f2=f2 ...
 - fetch gives data based on that comments where filters are true

5. user sees data based on its selection in deepest route at page
Avatar
DunkerOP
now i am asking the structure of backend routes of this frontend
like
// GET: /category/:id
 // 1 - in here i can fetch categories based on id
// GET: /category/:id/product/:id
 // 2 - but i am stuck here
// GET: /category/:id/product/:id/comments?f1=f1&f2=f2
for 2, i have solutions like join tables but not sure if its correct way
await prisma.category.findMany({
  include: { products: { include: { comments: true } } },
})

Category: {
  id: number;
  products: Product[];
}

Product: {
  id: number;
  categories: Category[];
  comments: Comment[];
}


First, i need to fetch all categories at first page, then after picking one, i ll fetch products for that category then so on...
Avatar
DunkerOP
I found solution, when i write 😂
i am leaving this here in case someone needs in future