How do I pass data to another page?
Unanswered
Schneider’s Smooth-fronted Caima… posted this in #help-forum
Schneider’s Smooth-fronted CaimanOP
My app is currently loading guild data every time you go to a new page which is super slow.
https://github.com/Astro-Birb/Website/tree/main
https://github.com/Astro-Birb/Website/tree/main
118 Replies
Schneider’s Smooth-fronted CaimanOP
Without query parameters
Schneider’s Smooth-fronted CaimanOP
.
is this every single page or just some?
@ASittingDuck is this every single page or just some?
Schneider’s Smooth-fronted CaimanOP
Some
Basically just the dashboard pages
first of all @Schneider’s Smooth-fronted Caiman you are using page router and dynamic routing
Ok lets check your dashabord directory
Schneider’s Smooth-fronted CaimanOP
don't judge 😭
@James4u first of all <@795743076520820776> you are using page router and dynamic routing
Schneider’s Smooth-fronted CaimanOP
im just doing router.push
and you are doing CSR
Schneider’s Smooth-fronted CaimanOP
Unsure I don't think
You have use effects in each of your dashboard pages that calls that explicityly
as an example
what about the contents, are they dynamic or static one?
@James4u what about the contents, are they dynamic or static one?
Schneider’s Smooth-fronted CaimanOP
no idea 😭
Schneider’s Smooth-fronted CaimanOP
Im quite new to next js
nope, it's not about next.js
This isn't the problem.
the content to render for different guild_id
Schneider’s Smooth-fronted CaimanOP
im quite new to ts
Its about you using useEffect in each of those pages and they each call that API
@Schneider’s Smooth-fronted Caiman it's not about typescript or next.js, just about your business
So of course the page is going to reload every time you go to that
what's the content like?
Schneider’s Smooth-fronted CaimanOP
Content?
yeah, the data you show in your dashboard page
Schneider’s Smooth-fronted CaimanOP
o
The thing you might look into is using useContext to keep certain parts of important data from page to page, HOWEVER this is usually built for keeping information about the user
A better way would be to use ISR
@Schneider’s Smooth-fronted Caiman Click to see attachment
is this page the same for different guild ids?
@James4u is this page the same for different guild ids?
Schneider’s Smooth-fronted CaimanOP
no
well the data it shows it is
Use ISR, you can have the system both create static versions of the pages AND you can set a refresh time
follow these steps
- check the content type (dynamic, static) and how frequenty it gets changed
- if it's static which means it doesn't get changed before you build then go SSG (static site generation)
- if it's dynamic and changes are too frequent, use SSR or CSR
- if it's dynamic but changes are not that frequent, use ISR
- check the content type (dynamic, static) and how frequenty it gets changed
- if it's static which means it doesn't get changed before you build then go SSG (static site generation)
- if it's dynamic and changes are too frequent, use SSR or CSR
- if it's dynamic but changes are not that frequent, use ISR
Hey @Schneider’s Smooth-fronted Caiman are you looking at those links, they are EXACTLY what you want
Schneider’s Smooth-fronted CaimanOP
i am looking at it
that's after you know what your content type is @Schneider’s Smooth-fronted Caiman
Right that is true. If you have a live feed, a CSR is much more your speed
If its like a blog post, its arguable (depending on if you a constant post editor like myself) if you will use SSR or ISR
However, it would be prudent to say that one piece of dynamic content should not determine your approach alone. If you have for example a card that is always changing but often remains the same, you should probably load it as a skeleton element and grab it there and load the rest of the page as a server rendered page.
Schneider’s Smooth-fronted CaimanOP
hm
Did that make sense, my last statement?
Also I see a lot of repeated call logic, you might think about refactoring this out so you can develop it more sucinctly if you need and make changes to the api call all at once instead of one at a time.
@ASittingDuck Did that make sense, my last statement?
Schneider’s Smooth-fronted CaimanOP
Kinda
I'm trying to read the docs trying to understand it all
Let me spin up an example page and you will see
This is a page that was just spun up with v0.dev. You have various elements. First you see elements that will always be there, the basic dashboard elements like the sitebar, the welcom message, avatar, etc. Those are things I don't want regenerated over and over because they will always be there. The app router excels at this because of the layout api. But there are some ways to do with with the pages router too.
The next is the settings card down below. imagine that he user's current settings were shown here. Likely this woudl be kept in the context and initially loaded by a session authentication process. But the app would keep track of it from page to page, whether it was going to use it or not. That means I have to be very lean with what i put here. Many people make the mistake of thinking useContext is about the page's context but its much more built for talking about an indivual session or user.
finally you have the cards up above. You can swap that out for a table, or a feed of posts, etc. If i made this page ISR, it would make it have to reload and replace the page every 60 seconds, and I would likely have to wait that long or less to get actual numbers that are 100% accurate at the time of the page load. Instead, what i can do is set these up with a loading skelton component that watches for a state. If the state is mounted for example, then that would mean my component has the data it needs to show the actual card. But that won't be the case when i first load the component UNLESS I make it look it up useing server side props. Not an ideal way of doing it IF you have a lot of data. For this example, it might actually work but again, that would still be a drag on load times, and when micro seconds count, its best to look into further optimization. So if this was a page I cared a lot more about those microseconds, I would instead fetch the data AFTER the page was loaded using useEffect like you are doing. It will be slower to get the actual data overall, but the page would load faster and my skeletons would show something was still loading and the user would know its coming.
Schneider’s Smooth-fronted CaimanOP
Alright
make sense? does that answer you question?
Schneider’s Smooth-fronted CaimanOP
Yea
I'm looking at these docs
Awesome!
Schneider’s Smooth-fronted CaimanOP
And it isn't really helping me pass the data to another page
that is another process entirely
What data are you wanting the application to remember from page to page?
Schneider’s Smooth-fronted CaimanOP
The Guild information and config information
So that would be data about the application itself as opposed to data specifically about the user or session right?
if you want the app to remember a piece of data, using react context CAN be a way to do that
But the cost to the performance can quickly outstrip the benefit
ISR is probably you're best bet because it will dynamically create pages, PLUS you can use the getStaticRoutes to prefetch certain guilds so that they will always be available. You can also limit the routes to a certain subset of guilds and refuse to server routes outside of that
this app shows a little bit how to do that when you look at pages/coffee-store/[id].js
Schneider’s Smooth-fronted CaimanOP
Uh okay
this app does two things. It first wants to know if it can find coffee stores near you and gets permission to do that. Otherwise it bases it off a default location. The fetch coffee stores lib item takes that into account and checks to see if location services are allowed and saves and remembers that so that it doesn't have to ask that on every page.
That is the part I chose to put into useContext. The ISR happens with the getStaticPaths and using a dynamic route ([id].js)
@ASittingDuck this app does two things. It first wants to know if it can find coffee stores near you and gets permission to do that. Otherwise it bases it off a default location. The fetch coffee stores lib item takes that into account and checks to see if location services are allowed and saves and remembers that so that it doesn't have to ask that on every page.
Schneider’s Smooth-fronted CaimanOP
I'm looking at ISR for this and how would this work?
export async function getStaticPaths(guildid: any) {
const paths = await fetch(`/api/discord/guild/${guildid}`);
const guilds = await paths.json();
}
so you just need to return a pages path array
as part of the returned object
make sure you map through your guilds and get the path ids into an array
Schneider’s Smooth-fronted CaimanOP
export async function getStaticPaths(guildid: any) {
const paths = await fetch(`/api/discord/guild/${guildid}`);
const guilds = await paths.json();
return {
paths: guilds.map((guild: any) => ({
params: { guildid: guild.id.toString() },
})),
fallback: false,
}
}
copilot just spat this out 😭 idk if this is rightlike this
export async function getStaticPaths(guildid: any) {
const paths = await fetch(`/api/discord/guild/${guildid}`);
const guilds = await paths.json();
const paths = Array.from(guilds).map(g => (g.id))
return {paths, fallback: true}
}forgive me for not making it TS ready
Schneider’s Smooth-fronted CaimanOP
👍
@ASittingDuck like this
js
export async function getStaticPaths(guildid: any) {
const paths = await fetch(`/api/discord/guild/${guildid}`);
const guilds = await paths.json();
const paths = Array.from(guilds).map(g => (g.id))
return {paths, fallback: true}
}
Schneider’s Smooth-fronted CaimanOP
so
export async function getStaticPaths(guildid: any) {
const paths = await fetch(`/api/discord/guild/${guildid}`);
const guilds = await paths.json();
const path = Array.from(guilds).map(g => (g.id))
return {path, fallback: true}
}
export async function GetStaticProps(guildid: any) {
const guild = await fetch(`/api/discord/guild/${guildid}`);
const config = await fetch(`/api/data/${guildid}/config`);
const guildData = await guild.json();
const configData = await config.json();
return {
props: {
guildData,
configData
},
revalidate: 10
}} copilot sent more codeyeah that would be helpful too so that the page gets the props to make the page dynamic
this is the server getting that data and then saving the page with that data
the revalidate makes it so that every path you specified and every path it has in its cache will be revalidated every 10 seconds
Schneider’s Smooth-fronted CaimanOP
do i replace this with either getstaticpaths or getstatic props or whatever
So you will be getting the data for the guild from the props passed to your component now
so instead of it being in a state, they will be a prop
@ASittingDuck So you will be getting the data for the guild from the props passed to your component now
Schneider’s Smooth-fronted CaimanOP
Does that mean I do?
So this is a question that requires a little longer to explain.
Say for example that you were using this to keep yourself from getting a stripe session in the client becuse you don't wanna expose your private key, if you use server props, your private env variables will be available but axios and fetch will not be because they are server side
client side
But in your case, it would be best to run an api call
Is there a discord api that lets you get the data?
probably best to use https://www.npmjs.com/package/discord.js?activeTab=readme
Schneider’s Smooth-fronted CaimanOP
Like this
So this is using http requests without a shell to surround and protect it. It works but its a hellova pain in the butt
using this will allow your code to run in a more modern way with using the SDK provided by discord, avoid using dicontinued api paths, and also allow your TS type hinting to more powerfully assist you with the rest of your application
Schneider’s Smooth-fronted CaimanOP
I tried discord.js but the issue is its asking for sharding but when I do sharding manager thing it stops working
What is sharding?
keep in mind I am not a discord developer, I have just only barely started to look at these docs
@ASittingDuck What is sharding?
Schneider’s Smooth-fronted CaimanOP
Sharding is a method to split portions of bots into separate processes. This is an enforced strategy by Discord once a bot reaches a certain number of guilds (2500). Once this number is reached, a bot must be sharded in a way that only 2500 guilds maximum may be allocated per shard.
So if you're running a shard it would likely need to stay up and working even if nobody is using the application right?
@ASittingDuck So if you're running a shard it would likely need to stay up and working even if nobody is using the application right?
Schneider’s Smooth-fronted CaimanOP
well yea
So the question has to be, did you run the shard on a part of the application that isn't going to to die
or at least will remake itself?
Keep in mind much of your application is serverless which means that there isn't a running process in the background
@ASittingDuck So the question has to be, did you run the shard on a part of the application that isn't going to to die
Schneider’s Smooth-fronted CaimanOP
idk
this ISR stuff is so complicated
Indeed, and I am trying to adapt it to the app router because I like the new features and apparently I hate myself enough to have to work around the app router's shortcomings as far as lack of redirect on dynamic paths
@Schneider’s Smooth-fronted Caiman this ISR stuff is so complicated
I highly suggest Zero to Mastery's course on NextJS 14, it is probably one of the best in the business as far as explaining this key aspect of nextjs and maximizing its potential in MULTIPLE use cases
@ASittingDuck I highly suggest Zero to Mastery's course on NextJS 14, it is probably one of the best in the business as far as explaining this key aspect of nextjs and maximizing its potential in MULTIPLE use cases
Schneider’s Smooth-fronted CaimanOP
Quite expensive costs like $23/m
Kinda, to most high quality learning platforms that is really comparable. For example, if you want full access to Codecademy (which usually is just text based although it does have a really nice practice as you learn interface), you need to pay $29.99 USD / month or