You have probably already figured out the solution but posting an answer so, it can be helpful for others.
Here is an quick overview of how we can convert the routes in react-router to Next.js routes/files.
Route in react-router |
Equivalent file in Next.js |
collection/:collectionid/analytics |
pages/collection/[collectionid]/analytics.jsx |
collection/:collectionid/auctions |
pages/collection/[collectionid]/auctions.jsx |
collection/:collectionid/items |
pages/collection/[collectionid]/items.jsx |
Inside each file, you would be able to access the collectionid
as a param to fetch files with data fetching
functions like getServerSideProps
or getStaticProps
like below:
export async function getServerSideProps(context) {
const { collectionid } = context.params;
// fetch data based on `collectionid`
return {
props: {}, // will be passed to the page component as props
}
}
More on dynamic routing here: https://nextjs.org/docs/routing/dynamic-routes
Regarding the routes for index.js
not being child of [address].jsx
, and [address].jsx
not being child of collection
.
Here is a table to compare what it would look like in react-router.
Files in screenshots |
Equivalent route in react-router |
/pages/collection/[address]/analytics.jsx |
collection/:address/analytics |
/pages/collection/[address]/items.jsx |
collection/:address/items |
/pages/[address].jsx |
/:address |
/pages/CollectionContext.jsx |
/CollectionContext *(probably should not be here if it's a context file?) |
/pages/index.js |
/ (home route) |
*= Any file inside of /pages/
dir is converted into a route/page in Next.js. So, files (hooks, contexts, etc.) that are not intended to be rendered as a page should be removed from this dir.
To solve this issue:
items.jsx does not seem to be a child of [address].jsx, and [address].jsx is not a child of collection
You can remove [address].jsx
and add /pages/collection/[address]/index.jsx
so, it's equivalent to /pages/collection/address
in react-router.
And to solve this:
Additionally I have tried to handle the sidebar + banner image using a nested layout, but the layout doesn't seem to be a child of collection either so it does not have access to the context state.
Based on this:
When a user goes to a collection/:collectionId, the banner image along with some basic details are fetched. This data should persist across the 3 subpages and should not be refetched, so I want a CollectionContext that wraps the three tabs.
Then for each tab, there are 3 separate data fetches depending on which tab the user is in:
- collection/:collectionid/items
- collection/:collectionid/analytics
- collection/:collectionid/auctions
I would like to have 3 separate contexts for these as well.
With this approach, fetching data (banner image and basic details) on colleciton/:collectionid
would make this a bit tricky in case the user visits collection/:collectionid/auctions
before visiting collection/:collectionid
. So, I would recommend fetching shared data on _app.jsx
file and storing it in the context there or in the layout file if you have a shared layout, or with a custom hook that will only fetch the data if it doesn't exist already in the context. And you would have to import all of them in the pages file and they won't be child of the collection.
layout doesn't seem to be a child of collection either so it does not have access to the context state.
Hope that helps.