So in the chatter on loading data,
we saw how you can export a load function from your page server JS and
your layout server JS files, but we can also export page options from those files.
We can export an SSR boolean, a CSR boolean,
a prerender value and a training value.
And these control how the page behaves.
And on the following exercise, we are gonna learn about each of these, in time.
All of the page options that we're about to discuss,
can be exported from individual pages,
or they can be applied to groups of pages by exporting then from a layout file.
So if you want some behavior to reply to your entire application,
you can put it in a root layout .js file.
And then in child pages, you can enable or
disable other aspects of that behavior as you need.
This allows you to mix and match different behaviors in your application.
For example,
you can have an application that is mostly prerendered as static HTML, but
has some dynamic pages that are rendered with personalized data for example.
And so this makes Spelke it very versatile for
whatever kind of application you're building.
The first one we're gonna learn about is SSR.
So Server-Side Rendering is the process of generating HTML on the server,
and it's what SvelteKit does by default.
It's very important for performance and resilience,
it's very beneficial for search engine optimization, right?
While some search engines cannot index content that is rendered in the browser
with JavaScript, it happens less frequently and it happens less reliably.
So SSR is a really important default to have.
Having said that,
there are some components that cannot be rendered on the server.
Maybe they expect to be able to access browser globals like Windows immediately.
And ideally you would change those components so
that they can be used on the server, but sometimes that's just not possible.
So in some situations you might need to disable server-side rendering.
We can do that in a page.server.js,
With export const ssr = false.
Right, and this will allow this page here to be rendered without breaking the app,
because if we were to server render this without ssr = false,
if you had the default ssr = true.
Then we get an internal error when we try and server render this page,
because window is not available on the server.
This is a component that cannot be rendered in a server environment.
The counterpart to SSR is CSR.
Client-Side Rendering is what makes the page interactive.
So here we have a button, when we click on it, it's gonna increment the count, right?
It also enables spelt kit to update the page upon navigation without
causing a full page reload.
And you can disable it using a page option add a page server.js file.
I'm gonna export const CSR equals false, right?
This means that no JavaScript is getting sent to the client at all.
But also it means that our components are no longer interactive,
if I click on this button nothing is going to happen.
So most of the time you're not going to use this option,
you're not going to use this option but
it is a useful way to be able to find out how your app is gonna behave for
users who, for whatever reason, cannot use JavaScript.
Okay, let's talk about prerendering.
Prerendering means generating HTML for a page once at build time.
Rather than dynamically for every request that comes into your server.
The advantage of prerendering is that serving static data is extremely cheap and
performant.
So it means that you can serve a very large number of users without worrying
about things like cash control headers, which are very easy to get wrong.
But the tradeoff is that the build process will take longer, and so
prerendered content can only be updated by building and
deploying a new version of the application.
So it's up to you when it's appropriate to use this.
If you wanna prerender a page then you just export const prerender = true,
again, from your page server js.
All right this isn't gonna have any observable effects here in the tutorial
because we're we're running the application in dev mode and
nothing gets prerendered during development,
this is a thing that happens when you run npm run build.
Not everything can be prerendered, right?
If you're building something that uses dynamic data,
then you can't have an HTML file for that.
Basic rule of thumb is that if any two users hitting that URL are gonna get
the exact same content in all circumstances.
Then that page is a good candidate for prerendering.
You can prerender pages with dynamic parameters like
earlier when we had /blog/slug and square brackets.
We can prerender things like that as long as SvelteKit can find them,
either by you having specified that in your SvelteConfig or by SvelteKit
being able to find a link to those pages from crawling your application.
So if you set prerender to true inside your root layout server.js,
then you've effectively turned SvelteKit into a static site generator.
This is what you would do, for example, if you're using adapter static,
which is the adapter that allows SvelteKit to build applications that can
be hosted on places like GitHub pages.
The final page option that we're gonna look at is trailingSlash.
So two URLs like /foo and /foo/, they might look the same,
but they are actually very different.
A relative URL like ./- will resolve to /- in the first case,
but /foo/- in the second.
And search engines will treat those two URLs as distinct, which harms your SEO.
So you don't wanna be loose about your trailingSlash.
You wanna pick one and stick to it.
And the default behavior that SvelteKit chooses is to remove trailing slashes.
So that if you do have a request for /foo/,
SvelteKit will turn that into a request for /foo.
So we can see that here, we have a bunch of URLs in the nav bar, and
if I click on always/, it's just gonna go to /always.
And these haven't been implemented yet, so they're all gonna behave the same way.
If we go to the always/page.server.js,
And add export const trailingSlash = always,
then now the behavior is gonna be reversed.
If I navigate to /always/, that's the URL that I get.
If I navigate to /always without the slash,
It will end up on the same place.
If we wanna accommodate both cases, which is not recommended,
then you can add the ignore value
Right, and now if I navigate to /ignore without the trailingSlash,
that's what I'll get, ditto if I add the trailingSlash.
There are very few situations where this is appropriate,
most of the time you will be using either, always, or never.
And this also affects prerendering.
If you have a trailingSlash,
then it'll be prerendered as an index.html file inside a directory.
If the trailingSlash is removed,
then a URL like /never will become never.html.
And that's something that you might need to configure with your static web server
if that's how you're deploying your application.
>> Have you seen people make installable PWA is was felt and do you feel like that?
Or have you seen traction with PWAs, whether it's worth it or
versus building something for the app store or whatever?
>> It's certainly possible to build a progressive web app with SvelteKit.
It gives you all the tools that you need to add a service worker and
you can add a manifest.json in your static folder.
It also works with a library called Vite Plugin PWA,
which does a lot of the grunt work for you.
So absolutely, it's something that you can do.
I couldn't tell you how widespread that is, how many people are building things in
that style, but it's completely achievable.
>> If I understand correctly, using prerender true and
layout.server.js is the same as using an adapter static.
>> You need to do both, essentially, if you use adapter static and you're not
prerendering, then it's gonna yell at you because it's gonna say, hang on a minute,
we have some non-prerendered routes here, and it'll tell you how to resolve that.
So if you are using adapter static, then you probably want
to have export cons prerendered true from your route layout.server.js.
But there are some situations in which you might have the bulk of your site
pre-endered, but then have a few things that only use client-side rendering,
for example.
And so it's not a hard requirement that every page in your app is prerendered if
you are usingadapter static.
You can use it to build a fully client rendered single page app for example.
>> I had a situation where the only way to find a link to get to some set
of blog posts and a prerendered TEDx it was to click through
a client side post paginator that had collapsed page
buttons that Svelte didn't like through all of the page links.
Is there a way to get some kind of file manifest for
all routes that SvelteKit finds?
So I don't have to made any update entries data and my SvelteKit config.
>> Yeah, hold that thought, so there is a pull request open on the SvelteKit
repo right now by Elliott Johnson, one of our core team members that
adds a new export from your page server js files called entries.
This is a function that you define per route when you have dynamic parameters.
It returns an array of all of the valid paths for that page.
So if you have something like /blog/slug,
then you can define an interest function on that file that.
Then it will communicate with your CMS, grab whatever data it needs to, and
then tell the prerenderer these are the pages that need to be pre-rendered.
Right now you have to do that in your Svelte config, but
very soon you'll be able to do it in the page itself.