SSR explained in SvelteKit - server-side-rendering

I recently started working with Svelte via SvelteKit and I have a few questions about this framework to which I haven't been able to find any direct answers in the source/documentation:
SvelteKit has SSR and in the documentation it says:
All server-side code, including endpoints, has access to fetch in case you need to request data from external APIs.
What code is server-side rendered besides endpoints and how it decides this? All the code from scripts from svelte pages runs on the client or some of it runs on the server?
In order to make use of SSR locally you need an adapter for it or does svelte start a server on its own?
How does SSR work in a production environment like Netlify for example. Is the netlify adapter is used for SSR (running the endpoints in a netlify function)? If a netlify adapter is not provided, how/where would the endpoints run?
If I want to use custom netlify functions in a sveltekit project what configurations are needed (besides netlify.toml and netlify adapter) in order for netlify to recognize the functions from inside the functions directory?
What is the difference here between SSR and prerendering? SSR is used only for endpoints and other js code and prerendering is used for generating the Html to send it to the client which will then be hydrated, with the compiled js code, also sent to the browser?
Thanks!

By default, pages are also server-side rendered when you first visit a site. When you navigate to a subsequent pages they will be client-side rendered.
Adapters are only used in production. If you run npm run dev for local development you still get SSR. In production, how exactly SSR is run depends on the adapter you choose. An adapter is required for production. adapter-node runs SSR on a Node server, adapter-netlify runs SSR in Netlify functions, etc.
See here for discussion of custom Netlify functions: https://github.com/sveltejs/kit/issues/1249
SSR is used for pages as well, but prerendering means that rendering happens at build time instead of when a visitor visits the page. See this proposed documentation for more info: https://github.com/sveltejs/kit/pull/1525

Pages are SSR when you first visit the site, including all the code in the script tag of your svelte page. However, as you navigate to other pages, the code will be run on the client and the page will be dynamically rendered as Sveltekit makes a single page web app look like it has different pages with the history API.
You can decide which code runs on the server and which runs on the client. If you don't do anything special, Sveltekit and your deployment environment will decide that for you. If you want some code to run only in browser (perhaps it needs to use the window object or need authentication), you can use the browser variable.
import { browser } from '$app/environment';
if (browser) {
// Code that runs only in browser
}
You can also put the code in the onMount function, which will be run when the component first mounts, which only happens in browser.
import { onMount } from 'svelte';
onMount(() => {
// Do stuff
})
If you want SSR, you can put the function in the load function in route/+page.js. One typical use case is for a blog entry that grabs the content from the database and populates and formats the content. If you get to the page from a URL, or refresh page, the code in the load function will be executed on the server. If you navigate to the page from elsewhere in your web app, the code will be run on the client, but it will look like SSR as the UI will refresh only after the load function returns (you won't see loading screen or a blank page). See the official docs for more for more.
import { error } from '#sveltejs/kit';
/** #type {import('./$types').PageLoad} */
export function load({ params }) {
if (params.slug === 'hello-world') {
return {
title: 'Hello world!',
content: 'Welcome to our blog. Lorem ipsum dolor sit amet...'
};
}
throw error(404, 'Not found');
}
I am not very sure about how to use Netlify function, as Ben mentions, you can see the discussion on https://github.com/sveltejs/kit/issues/1249. Although I think that you might be able to implement the same functionality with +page.server.js, and the "Actions" to invoke them.

Related

Why quassar with ssr mode behave like a SPA

i have an ssr quasar app , when i lunch the website for the first time in chrome developer mode i see that the server return an html document.
but when i navigate to another page the server return only js scripts soo not rendering at the server side , it behave like a spa after the first page,
Is there any parameters i can change to render all the page at the server side ?
i read all the documentation regarding quasar ssr mode but couldn't find anything
and here is how the ssr config object looks like inside quasar.config.js
ssr: {
pwa: false,
prodPort: 3000, //
middlewares: [
'render', // keep this as last one
],
},
This is by design. Quasar is VueJS based, which (unlike e.g. PHP) focuses on delivering pages basically as SPAs, i.e. giving you data + JS to render it.
SSR only means that the first page is rendered on the server (e.g. for SEO purposes) and javascript takes over for fetching and rendering all subsequently loaded pages (or better the data + a recipe to render them) on the client. Thus, SSR will only get you server-side rendered pages upon initial load or page reload, all other renders are client-side.
You may learn about SSR, but also SSG (Static Site Generation), that might fit your needs, here: https://vuejs.org/guide/scaling-up/ssr.html

Why is Next.js _app.js called by both client and server? [duplicate]

In a Next.JS app, you see that the code for a component runs on both the Server and the Client.
So if you have the following code:
const Title = () => {
console.log('--> Hello')
return (<h1>Some title</h1>)
}
and you run this in a dev environment (npm run dev), you will see the console.log statement print to both the Server in the terminal as well as the Browser's console.
So firstly, what is happening here? How come all the code on the page gets run in both places on every page load?
Wouldn't Next.JS just sent a pre-transpiled HTML file to the Browser? How come that console.log statement is getting run in the Server even though we're not in getServerSideProps or something similar?
Now, this may be a core feature of React that I've overlooked, so please tell me if it's just that manifesting in Next.JS
Wouldn't Next.JS just sent a pre-transpiled HTML file to the Browser?
Yes, this is correct. But to transpile it to html it first needs to run your app and render it with ReactDOMServer.renderToString method.
So it is not specifically Next.js feature, but just a React SSR thing, every similar framework would do the same thing.

Issue with Service Workers when switching from CRA to Next JS

So we recently changed our landing page from create-react-app to using Next.js. Our old create-react-app had a basic default service worker registered on users browsers.
Whenever I switched over to our new Next.js website, we realized that users who had been there before would continue to get a crappy cached version of the old website.
I've found a couple of discussions talking about this issue already, but neither solutions seem to be working for me. Those two discussions are:
A website is not refreshing because of caching of service worker, after switching from React to Next.js. How to force update?
https://www.asapdevelopers.com/service-worker-issue-nextjs-framework/
Both of these solutions essentially consist of adding a new service worker file to your Next project with some code to delete the existing service workers. That code looks like
if ("serviceWorker" in navigator) {
window.addEventListener("load", function () {
navigator.serviceWorker.getRegistrations().then((registrations) => {
console.log("--");
for (let registration of registrations) {
registration.unregister().then((bool) => {
console.log("unregister: ", bool);
});
}
if (registrations.length) {
window.location.reload();
}
});
});
}
So i've tried this. My old service worker was served via a file at route OUR_URL/service-worker.js. I added a public directory to my Next project and added a file with the same name and the code above to my project. I then linked this file in my _document.js and can confirm that it runs, as well as I'm able to find it on my Next.js site. The URL for both the new and old files are identical. Unfortunately though, it looks like the issue persists.
In one of the other articles linked above, it also mentions putting this file in the root directory of your Next project. This doesn't make much sense to me as it isn't then being served in anyway that I'm aware of, but I gave this a shot as well, still with no luck.
Anyone have any idea what I might be doing wrong here, or what I could do to fix this? Essentially we just want to force remove any and all old service worker so that our new website loads correctly.
Service workers are (at least generally) registered via the site itself and not automatically found by browsers (at least not yet).
This code (unregistering all service workers for the domain) should go in whatever is being sent from next.js to the browser (e.g. index.js). If you put this on your home page all users going there should have the problem resolved. If you have reason to suspect (based on traffic data) that users have other pages bookmarked you might want to include this in a universal bundle or footer.

NextJS extremely slow

I'm working on a website on nextjs but the Link component and the router is kinda driving me crazy. When I click on a link it has an horrible delay before accessing the page and then if you use the browser back button the page don't change, just the url.
Here is the link of my site, don't really know what is happening actually.
https://next-madeleine.tmsssss.vercel.app/
It is common for Next.js and other frameworks as well to be slow in development time. As I can see and confirm in your production live website, the links work well, even great. That it because in development there are certain tools and packages being used by Next.js and webpack to compile on-fly the code. Those tools are disabled and removed in a production build of course, and the pages are cached by Next.js.
So, try to run npm run dev and compare it with npm run build, followed by npm run start
NextJS runs getInitialProps, getServerSideProps and getStaticProps every time you link to a page, which might be time consuming. You can skip this by shallow routing your page. Link accepts a boolean prop called shallow={true}.
<Link href='/your-page' shallow>Your Page</Link>
With Next's router.push:
router.push('your-page', undefined, { shallow: true })
Read more about Shallow Routing - https://nextjs.org/docs/routing/shallow-routing

Pages with `getServerSideProps` can not be exported

I think i am making some kind of confusion here.
According to the documentation, if i want Server Side Rendering (SSR) for the page i export the async function:
getServerSideProps
But if i do that i can't build the project for running either locally or now Zeit now.
If i try build or deploy i get:
Error for page /_error: pages with getServerSideProps can not be exported. See more info here: https://err.sh/next.js/gssp-export
The link provided by the error says i can't export. But I used the example from the documentation below:
import React from "react"
export async function getServerSideProps() {
return { props: { } }
}
function Page({ data }) {
// Render data...
}
export default Page
Do i have to change some configuration somewhere?
How to prevent from building this static page?
getStaticProps() is the way to go under the following conditions:
The data required to render the page is available at build time ahead of a user’s request
The data comes from a headless CMS
The data can be publicly cached (not user-specific)
The page must be pre-rendered (for SEO) and be very fast — getStaticProps generates HTML and JSON files, both of which can be cached by a CDN for performance
Refer here for when to use getStaticProps vs getServerSideProps
https://nextjs.org/docs/basic-features/data-fetching/get-static-props
vs:
https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props
Won´t work on page _error.js, by design decision, as posted here by nextjs maintenance staff.
One possibility is to use getInitialProps, instead.

Resources