-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Separate Load Functions for Server and Browser #10004
Comments
This would be breaking. You can already have both |
They are both executed. You can use the event.data in your shared load function on the server and execute different code when running in the browser haven't tested this, writing from my phone export const load = (event) => {
if (!browser) return event.data;
return { custom: 1234 }
} |
@tcc-sejohnson - Didn't realize that, good to know. However, this doesn't solve the problem of running them separately instead of consecutively. @david-plugge - Not sure what you mean. I can check for the browser on the Perhaps then the best feature request would be:
J |
I'm a bit confused about what you're trying to accomplish. There's a very high chance it's already possible. Can you describe the actual use case a bit more? |
@david-plugge - So it seems I can skip the load function on export const load = (async ({ params, request }) => {
// don't run after loaded once
if (request.url.includes('__data.json')) {
return {
...
};
}
// otherwise fetch data from database...
// return fetched data...
}) satisfies PageServerLoad; However, this won't help as the @tcc-sejohnson - Yes, I want to run two different load functions: one from the server on first load, and another from the browser on every other load. This is how the load function works now if you use only Here one example with Posts:
As you can see here, the app is over fetching, or basically violating the Here is how I should be able to do it:
That is my specific problem. There is a workaround with an endpoint, but that creates additional developer overhead and an endpoint I don't need. However, there should be a way in SvelteKit to have two completely different load functions depending on if the request is from the browser or the server (instead of sharing a load function). J |
Yeah, all of these needs are taken care of one way or another:
// +page.server.ts
export function load() {
return { foo: 'foo' }
}
// +page.ts
export async function load({ parent }) {
const { foo } = await parent()
return { bar: 'bar', foo }
}
The above should get you as far as you need, but architecturally, you should probably put these |
Ok, so you definitely got me where I needed to be after changing your code: +page.server.ts export const load = (async ({ isDataRequest }) => {
if (isDataRequest) {
return;
}
// fetch data
...
return {
post: data
};
}) satisfies PageServerLoad; +page.ts export const load = (async ({ data }) => {
if (browser && !data.post) {
return {
post: get_data_from_store()
};
return data;
}) satisfies PageLoad; So, for future references, this particular problem has the above work-around solution. That being said, I still think it would be better if they were separate functions entirely. I also digress now that I found a new issue... what if the post is not in memory because the user did not come from a post-list page, but a link from somewhere else on the site? No way to condition the
Still same issue, just layout files, but I get your point. J |
No, actually! The layout load shouldn't rerun unless a dependency changes. So if you put your |
Ah, yes very true. I don't think that helps me in this particular situation, as I need to not get the slug on route change sometimes, but good to know, thanks! |
For clarity, #10004 (comment) isn't quite right — if you have // +page.server.ts
export function load() {
return { foo: 'foo' }
}
// +page.ts
-export async function load({ parent }) {
- const { foo } = await parent()
+export async function load({ data }) {
+ const { foo } = data
return { bar: 'bar', foo }
} The canonical solution here is to use an API route. On the server, So it seems to me that the two concerns are
There's an idea here for typed API routes, but it sounds like you really want something like tRPC (via e.g. trpc-sveltekit) or telefunc. So to me the question is whether it's enough that the problem is solved in userland (this seems pretty nice, honestly) or whether the framework needs to introduce new primitives. |
Very very interesting and good to know! In the end, I needed an endpoint to cover my needs. I don't want the extra overhead or configuration of TRPC when SvelteKit works just fine. But you're right, endpoint is what I needed. Thanks! J |
This way of coalescing data from server load and client load is nowhere to be found in the SK documentation. If found this issue after hours of googling... Thanks a lot! |
Describe the problem
Right now there is not a way to separate them. We can run the same code in
browser-only
,server-only
, orboth
, but there is no way to run SEPARATE code in bothserver-only
,browser-only
versions.Most database fetches cannot be run in the browser. This can be fixed by using just
+page.server.ts
, however, this forces a new database call from the server on each route reload. What if I want DIFFERENT code depending on if it is a server or browser call? This is currently impossible. You can't use theif (browser)
option, as it will load the same code and packages for the server, which you don't need or can't use in the browser.The only work-around is to completely move your server load function code outside of your load function, and create and endpoint. That way you can do:
if (!browser)
, fetch data from the endpoint. This is extremely problematic, as you are forced to create an endpoint for something that is already loading on the server. This enables access to your data from an endpoint, which you don't want. Plus, with endpoints, you lose type-safety like you have withPageData
or$page
.Describe the proposed solution
The most logical solution which would allow backwards compatibility is to allow BOTH the
+page.server.ts
file AND the+page.ts
files. If it is the initial load, it will run+page.server.ts
, and every call to the component afterwards will run the+page.ts
file.Alternatives considered
+page.browser.ts
file.export const separate = true
+page.ts
file (loadBrowser, loadServer)Importance
would make my life easier
Additional Information
I can use SvelteKit without it, but I cannot use it correctly without an extraneous endpoint.
A good example of this is a feed. When I click on the item on the feed, I should not have to refetch that item if it is already in memory. There is no way to do this without an extraneous endpoint if I can only fetch the data on the server. With Firebase, for example, this could also potentially add extraneous read costs.
The text was updated successfully, but these errors were encountered: