How to return data from server to page and set it to localStorage in sveltekit?

2.2k views Asked by At

Context is an object which I want to save to LocalStorage. In page.server.js I am returning context like this:

      return { success: true, userInfo: context};

In page.svelte I can access the object and it's attributes. There is a function which saves the object to localStorage which works when there are no redirects and I call it like this:

            {#if form?.success}
              {$LoginStatus = {
                loggedIn: true,
                userInfo: form?.userInfo
              }}

My problem is that the page redirects if the user is logged in and (quoting svelte's documentation) the page is ephemeral. What I think the problem is that the page redirects to another page before it can call the function to save context to localStorage.

How can I fix this problem so that context gets stored to localStorage successfully?

1

There are 1 answers

1
Leftium On

It looks like you're using the SvelteKit form actions API.

You are trying to persist data returned from the form action in the page component on the client/browser. However, the main purpose for values returned from a form action is just to update the form (for example: display validation errors or a success message.)

Ideally the form action should persist the data itself before returning. Now, the form action does not have access to localStorage, so you should use something like a database and/or cookie.

If the form action updates a database, the SvelteKit page can load the updated data in its load() function.

Now, when logging in a user just updating the database is not enough: credentials need to be saved on the client (browser). So the database server usually returns credentials that can be saved in the browser. The form action will receive these credentials (on the server side of SvelteKit) and send them to the client/browser side of SvelteKit via cookies.

These cookies will be sent in the headers of all future requests. By default, these cookies cannot be read by JavaScript, but that page load() function runs on server. So the load() function can read the cookie and return the values, which can be accessed from the SvelteKit page from its data prop.

Just using the cookie should be enough, but for completeness: after you get the data prop, you are free to save it to localeStorage at that point.


A log in form can be quite daunting, since it requires combining multiple things like SvelteKit's cookies, form API, etc. Just learning the SvelteKit page routing + load() is difficult enough!

It is possible to add log in to a SvelteKit project without all these things by using a 3rd-party authentication service. I recommend Userfront. They don't have official guides for SvelteKit, but I made a sample project (using an old version of SvelteKit): https://github.com/Leftium/userfrontKit/

Userfront has guides for plain HTML, React, and Vue which would help you create your own SvelteKit version.

I have integrated Userfront with the most recent version of SvelteKit using form actions (unfortunately cannot share.)

The nice thing about Userfront and SvelteKit is you can choose the level of integration:

  • Use Userfront's toolkit with pre-made forms.
  • Use Userfront's core JS API to roll your own SvelteKit forms (client-side only, requires JS)
  • Use Userfront's client-to-server API to roll your own SvelteKit progressive forms (server or client+server, no JS required)

All the methods above store user info/credentials in a cookie which can be accessed from both the server and client.