Transcript from the "Loading Data on the Server" Lesson
>> Very often your routes will have dynamic parameters. That means that you'll have a single route that can serve multiple pages. So here for example, we have a blog/[slug]/.page.svelte. That creates a root that will match blog/one, blog/two, blog/three, and so on. At the moment, that file doesn't exist, so let's create it.
[00:00:32] But for now we'll just put in some static placeholder content, And if we navigate to any of the pages that are defined by that route, then we'll see that same static content. Now the way that dynamic parameters are defined is actually very flexible, you can have multiple parameters in a single segment.
[00:00:53] You can have multiple parameters in a route, and we'll learn more about complex routing patterns later on in the workshop. So SvelteKit's job boils down to three things. There's routing, then there's loading some data that's needed by the route, and then ultimately rendering the HTML or the DOM that that route defines.
[00:01:20] And we've seen the routing part and the rendering part, now we need to learn about data loading. Every page of your app can define a load function in a page.server.js file alongside the page.svelte file. As the file name suggests, this module only ever runs on the server, even for client-side navigations, where we get the data using fetch.
[00:01:43] So we'll add a blog/.page.server.js file so that we can replace those hard-coded links, the one, two, three, with some blog post data that's defined in this module here, data.js. So in the blog directory, hit the new file icon and create +page.server.js. And then we're gonna type out the contents of this file.
[00:02:13] Now we covered this in the Svelte part of the course, but if you're tempted to just select this and copy and paste it into the editor, it's gonna pop up with a warning saying that you shouldn't do that. And the reason is that you will learn much more effectively if you do, in fact, type out the code yourself.
[00:02:30] You'll develop better muscle memory, and you'll notice things that you would not notice if you were just copying and pasting. So I do urge you to resist the temptation to enable copying and pasting. So let's do this, import posts from /data.js. And then we're gonna export our load function.
[00:02:56] For now, we don't need all of the post information, we just need the summaries, because the post content isn't important until we visit the blog post itself. So we'll create a Summaries property here, posts.map post, and then we'll return, A slug so that we know where to navigate to, and a title so that we can populate the list.
[00:03:27] There's little call out here. For the sake of the tutorial, we're importing data from this data.js module. Obviously in a real application, you will be pulling this data from your file system, from the markdown files, or from a content management system, or a database. But for the sake of this tutorial, we're gonna keep it simple and import the data directly from a module.
[00:03:47] And we can access this data in page.svelt by exposing a data prop. So go over to that file, and we'll add a script element at the top of the component. And everything that is returned from that load function is gonna be available now on that data property. So we can get rid of all of these and replace them within each block that iterates over the data array, and renders a list item.
[00:04:30] Replace the hard-coded one with slug and the hard-coded title with title. I'm now seeing some content being rendered. Of course, if you visit these pages, then we still see that hard-coded content on the blog's slug page.svelte file. So let's fix that. Let's create another file that loads data for an individual blog post.
[00:05:03] Inside the blog's slug directory, create a new file, again, page.server.js. And inside here, we'll import from that module again, import posts from ../ this time because it's one directory higher. And again, we're gonna create a load function. This time, we're gonna use the params object, because that's how we're gonna know which slug we need to load data for.
[00:05:37] So of all the posts in the array, we're gonna find the one, Where the slug matches the current parameter. Then we're simply gonna return that. And now we can create a data prop on the page component, and use that to inject the content. All right, so we have our title, and then we'll create a container for the content itself.
[00:06:26] We're gonna use the HTML tag, and as we discussed in the Svelte course, this is something that you should only use with data that you trust. Never use it with untrusted data that was submitted by users, for example, because it is not sanitized, then you could expose your users to a cross site scripting vulnerability.
[00:06:47] Okay, so we now have some data powering that h1 and the div below it. There is one last detail that we need to take care of here. Someone could visit a nonexistent post, and when they do that they'll get an error because we haven't been able to find the post in order to render it.
[00:07:09] And we wanna give them a more informative error than a 500. This should in fact be a 404, so we need to take care of that when we load the data. Go back into the blog slug page server.js file, and after we've declared the post variable, we'll say that if we don't have it, then we need to throw an error, which is gonna be a 404.
[00:07:31] And we need to import the error helper from SvelteKit. So we now see the appropriate 404 error page. We'll learn more about error handling later on in the workshop.
>> Can you have a loading page that shows with a spinner before the plus page.tsload function finishes and plus page.svelte is rendered?
>> Yes, you can. Unfortunately, because of a technical limitation with web containers, which is the technology that powers this website, I cannot demonstrate streaming in this tutorial. What I can do is show a little demo that has been put together, this sveltekit-on-the-edge. So this is a page that is being rendered dynamically in an edge function.
[00:08:31] Is Osseo near here? I don't know if that's the nearest point of presence that this page is being rendered at. And if I click on the streamed link here, then it's actually gonna get some data from the server that is gonna be delayed. So we're actually able to stream promises from the edge function, or from the serverless function, or from your server, and they will be rendered in the browser when the promise resolves using streaming.
[00:09:05] So that's how we approach that problem. We don't have a dedicated loading page or something like that. Instead, you return promises from your data, and in that way you're able to render the UI that is most appropriate for your case.
>> There was another question that came in around, Kind of, there's Svelte Native for mobile but have you seen any traction on that?
[00:09:37] Not knowing too many people talking about Svelte Mobile, just wondering if that's a good route, or if you're thinking about mobile?
>> I haven't personally used Svelte Native. Some people have, I believe it is an up-to-date and functional project, and it's the only one that we have, as far as I'm aware.
[00:10:00] So if you do wanna build a native app, then I definitely recommend giving Svelte Native a look. But it is not an officially supported project that comes from the community. It's something that if we have time and bandwidth to do, we would like bring into the organization at some point and have that as a first class project.
[00:10:15] But right now it's a little bit, your mileage may vary.