I can't make sense of the docs on this at all.
I'm assuming:
+page.server.js
= code that runs server side (fetching data from db etc.)+page.js
= code that runs client side (dynamic stuff in the browser)+page.svelte
= the main front end.
As a specific example, I have a data.user.startdate
prop in my layout that I want to manipulate so I can display the difference between now and start date.
+page.svelte can access this no problem here:
<script>
export let data;
</script>
And I could just manipulate the data here, however I'm assuming best practice would be to do this in +page.js
But +page.js
seemingly have no equivalent way to access the data prop, without some sort of parent inherit, which is messy compared to +page.svelte
I believe the main issue is likely my understanding of the purpose of the sveltekit files, hence the question is about the framework files.
As a side note, why the +
signs, and what's best practice in searching files in VS Code, as all route files are named the same!
I can't make sense of the docs on this at all.
I'm assuming:
+page.server.js
= code that runs server side (fetching data from db etc.)+page.js
= code that runs client side (dynamic stuff in the browser)+page.svelte
= the main front end.
As a specific example, I have a data.user.startdate
prop in my layout that I want to manipulate so I can display the difference between now and start date.
+page.svelte can access this no problem here:
<script>
export let data;
</script>
And I could just manipulate the data here, however I'm assuming best practice would be to do this in +page.js
But +page.js
seemingly have no equivalent way to access the data prop, without some sort of parent inherit, which is messy compared to +page.svelte
I believe the main issue is likely my understanding of the purpose of the sveltekit files, hence the question is about the framework files.
As a side note, why the +
signs, and what's best practice in searching files in VS Code, as all route files are named the same!
3 Answers
Reset to default 8+
is used to mark files reserved by svelteKit to answer why +
specifically for the same reason why /
is used for commands just because they needed to use some uncommon symbole in the beginning of the name.
+page.server.js
The following file is run on the server so it is used to fetch data from some API which requires an API key and then you just send the data to the client, that way your API key wouldn't be exposed to the client.
+page.js
is just a file where you can have js for the page, so you might want to move some function that has a lot of logic and is a bit too big in there. (So you will most likely not have this file for every page)
+page.svelte
is where your frontend is, so your HTML styles and js.
+page.js
vs +page.svelte
So +page.svelte
can in theory do what +page.js
does, but it allows to do it in a simpler and possibly more efficient way, notably when considering asynchronous calls:
Usecase 1: no need to worry about undefined values in asynchronous calls
What +page.js
is great at is to load asynchronous data before the page loads, since it is not possible to write in the +page.svelte
file an asynchronous operation like:
let db = await new Dexie($page.params.uuid).open();
While it is possible to write something like:
let db;
$: {
(new Dexie($page.params.uuid).open()).then(e => { db = e; });
}
it is not super practical as db
will not be set from the very beginning, so all the code needs to take into account the fact that db
might be undefined (which occurs only during .1s…).
By writing instead in the +page.svelte
:
let db = $page.data.db;
and in the +page.ts
:
import type { PageLoad } from './$types';
import { Dexie } from "../../../db";
export const load: PageLoad = async ({ params }) => {
const db = await new PlanotoFileDexie(params.uuid).open();
return {
db: db
};
};
the db
is guaranteed to be populated and we never need to check for undefined
values inside the .svelte
code.
Another option might be to use onMount
, but, as explained in discord by Rainlife:
this runs only once when the component is mounted, and if you move laterally from page to page (meaning from /project/123 to /project/456) the slug changes but the page component itself does not change thus onMount does not run again, now you have to detect that and do those yourself
Usecase 2: Server side rendering
As pointed by Rainlife in discord:
another benefit is that for the first render the page.js load also runs on the server and thus it can do server side rendering making your site feel faster because you don't first get an empty screen or 'loading' indicator but immediately the content you are looking for.
+page.{js,svelte}
vs +page.server.js
As pointed in other answers, the server
flavor only runs on the server, so you can also use private credentials (API keys…) since this will not be sent to the client.
In addition to the details provided by @Laycookie I would add that while +page.js
and the content of the <script>
tag inside +page.svelte
are both client side Javascript, there is an important difference regarding certain reserved statements that only work inside +page.js
.
For example, when building a static site, to mark a route to be prerendered, the documentation points you to include this statement:
export const prerender = true;
which will only work inside the .js
and not the corresponding .svelte
file (presumably because you can't export injected JS?). So, watch out for the file extensions in the documentation and error message.
See also this article on other statements that only work in the .js
file.
+page.server.ts
is server side only,+page.ts
is "universal" (executed on server side and on client),+page.svelte
only client. Read again the official routing docs, have a look at the video I told the link and eventually ask again and someone (maybe me) will write a proper answer. <3 – Paolo Commented May 13, 2023 at 19:34