Svelte Simple Login With Local Storage And Stores

Al Javier
7 min readJan 28, 2022

So you decided to learn Svelte, but have no idea where to begin in creating your simple login form? Or maybe you’re like me — a React developer trying to loosen up and realize not everything is as rigid as React’s state management.

The real cool thing about Svelte is that you only really need to know HTML/CSS, and a handful of Svelte-specific JS syntax. The rest is almost pure vanilla JS. Before we begin, this small guide of sorts assumes you have some knowledge of the aforementioned Svelte-specific things, and of course, understanding of Javascript/Typescript.

Prerequisites:

  • You finished the Svelte interactive tutorial (it’s fun!) 😆
  • Any text editor or IDE with a terminal
  • That’s it…?

Let’s proceed! 😎

The App

Alright, we’re going to create something utterly bare bones, so it may be off-putting at first, but don’t worry, you can style it later. Maybe end up with something below:

Carbon Design System is sleek

For now, let’s initialize our app with some commands:

$ npm init svelte@next local-stores-login # or whatever app name
$ cd local-stores-login
$ npm install # or pnpm/yarn etc.

If it asks what type of Svelte app you want to create, just pick the skeleton one. The rest of the options like ESLint and Prettier, as well as Typescript are all optional.

Normally when we begin building our Svelte app, we first create a __layout.svelte file at the root of src/routes directory, then apply the styles to our layouts. But we’ll leave that step out for now.

Local Storage and Store

Since Svelte runs a hybrid between Server-side and Client-side rendering, it’s a little tricky to get Local Storage to function properly with the Store. The first road bump you’ll encounter is the all-too-common localStorage is not defined error. Next.js developers are very much familiar with this. 😑

GIF by meguygama

There are a couple of well-known NPM libraries out there that wrap around Svelte’s Store and allow it to have Local Storage, and make it just work. For this one though, I found a good way to do it without the need for a third-party library, and it’s only a few lines of extra code so don’t worry.

Check out this super helpful guide for more information.

Create a new file at the root of src and call it store.js. This will contain our user store, and all the things needed to use Local Storage properly.

So, what the heck is going on here? 🤔

First, we create a variable called persistedUser which has some ternary magic going on. The browser boolean comes from SvelteKit and gives us an easy way to check if we’re running on the Server or Client. This avoids undefined errors for Local Storage.

Second, we create our actual writable store called user which also happens to have some ternary stuff inside. We’re simply checking if the value of persistedUser is falsey, if it is, we initialize the writable with an empty string — which is the easiest way to make anything in Local Storage falsey. Anything you store in Local Storage is a string, keep this in mind. Even the value of undefined becomes a string "undefined" which presents a weird problem. That’s the purpose of all the checks we put in place.

Finally, we got our subscription at the bottom. This checks every time the value of the Local Storage is updated, and instantly assigns that value to the user store. We’ll talk about this in more detail later.

Building The Forms

The form itself is really simple, just a couple of <input /> tags and a button to submit the information. Take a look at the HTML tags at the bottom of the source.

Wow, that’s a ton of code though. 😯

Take your time and just write those HTML tags for now, including the {#if} blocks. Those are important.

Okay, top-to-bottom. We first initialize the subscribed state in the form of user_value. Directly below that is the subscription, which assigns the whatever value user has directly into user_value on every update. This creates reactivity in your UI. We then define unsubscribe to use in the onDestroy function.

Next, we have our handleLogin() function. This first checks if any of our fields are empty, if they are, alert an error message and stop function execution. Then we update the store using user.update() and assign the new value as a stringified object (recall that localStorage only accepts string values).

UPDATE: You may also want to call JSON.stringify() in your Store’s subscription. This will prevent local storage from storing your object as [object Object].

The handleLogout() just updates the user store and assigns an empty string as the new value.

One of the HTML tags at the bottom, specifically line 42 with the <h3> tags, you can see something funky going on with the JS expression. Basically, we’re parsing the value from user_value which is a stringified JSON. This allows us to access its properties like you would with a JS Object.

Alright, that’s all of it. So, what does it look like?

Launch the development server:

$ npm run dev -- --open

And here’s our app!

Yeah… It’s not beautiful. But it will have to do for now.

Testing Time

Type whatever email and password, then click on the Login button. Then check the output.

This should’ve removed the form and started displaying the email address you typed at the top. And don’t forget to hit F12 on your keyboard (or maybe you’re a 60% keyboard user, inspect the page and go to console).

Our little debug line should’ve seen the store update immediately.

Now, try clicking on the Logout button. That should’ve taken you back to the login form. And the console should report that the store is now just an <empty string>.

If your testing went as smooth as this, then congratulations, you’re done! 🥳

But this probably leaves more questions than answers, right? Don’t worry, let’s try to clear those up.

Wait a minute, Local Storage for Authentication?

Ah, the ever looming doubt that you’re doing something wrong as a web developer once you start using Local Storage for storing user information. I get this a lot too.

GIF by からめる

Before I dig any deeper on this matter, I want to make this as direct as I can. Don’t store any sensitive information in Local Storage, this includes Access/Bearer Tokens (JWT). Okay, now that we got that out of the way, let’s try to answer other questions.

What are you supposed to store in Local Storage anyway?

This will highly depend on your project’s requirements. This may range from theme settings, user preferences, and even some client-side user information. To give an example on one of my projects, I have a server application that sends the client a JWT that contains some basic details about the logged-in user, like their avatar URL and biography. The real access token is sent as httpOnly cookie.

Cookies?

I made an entire guide about creating httpOnly cookies with Node.js and Passport right here. (Go version coming soon 😉)

In brief, httpOnly cookies are different in that the client (our Javscript) cannot manipulate its value. This prevents cross-site scripting attacks (XSS). You’re supposed to combine the security of this, and the utility of Local Storage to create a much better developer experience.

Why not just plain Store?

I’m sure if you’re an experienced front-end developer, you already know the answer to this question.

No, we don’t use just Svelte’s Store because it alone does not have data persistence. What do I mean by this? Simply put, when you refresh the page without persistence, the information inside the Store resets the the initial value.

To have both reactivity and persistence, you need Store and Local Storage together.

What’s Next?

You can call it a day and start a new project with your new found knowledge. Or maybe you want to style the app you’ve just created. It’s up to you! 😁

That’s It For Now

We’re done! I really enjoy using Svelte (probably more than React at this point). What about you?

GIF by Mateusz53

Anyway, if you made it this far, thanks a lot. I hope I was able to help you, or at least cleared up a few things. If you have questions, I’ll try to answer them when I can.

For those that feel especially generous, consider supporting me by grabbing me a coffee. This helps a lot and allows me to keep making more guides like this one.😊☕

Alright, see you in the next one!

--

--

Al Javier

Alphonso ‘Al’ Javier is a web developer and rookie entrepreneur that enjoys food, travel, and a good dose of gaming.