861: Local Data: Sqlite, LocalStorage, Session, Cookies and IndexDB ![rw-book-cover](https://wsrv.nl/?url=https%3A%2F%2Fstatic.libsyn.com%2Fp%2Fassets%2F6%2F4%2Fb%2F8%2F64b8ee9cb432ec4188c4a68c3ddbc4f2%2FSyntax_Cover_Art.png&w=100&h=100) ## Metadata - Author: [[Syntax - Tasty Web Development Treats]] - Full Title: 861: Local Data: Sqlite, LocalStorage, Session, Cookies and IndexDB - Category: #podcasts - URL: https://share.snipd.com/episode/fd1549de-a101-42f2-8ced-8858c7ac32be ## Document Notes ## Highlights - **Local Storage for Preferences** - Store user preferences and settings locally to avoid unnecessary database trips. - This is especially useful for frequently changing data like video playback settings. Transcript: Scott Tolinski What's up, my man? How's it going? Wes Bos Hey, let's talk about storing data locally. There's lots of ways you can store data in the browser. But let's talk about why you might want to store data in the browser first, right? Probably the first one is user preferences and user settings. You don't necessarily always have an account for somebody to store that in. It doesn't make sense to always send that data back to the database every single time that it changes. So one example I'll have is on my course platform, as people are watching the videos, every... I forget how long. Every time that the video current time updates, which can be every two to three seconds, I'm putting that data in local storage. And same with playback rate, volume level, like all those settings, right? I'll stick that in local storage and then periodically they'll get synced to the backend. But it's nice to stick that in local storage or in the browser when you need it immediately. Scott Tolinski Yeah, another thing too often that like, I think you see this a lot more in native apps, which is something that people might be doing on the web more and more these days is letting you use The thing before signing up for an account or even maybe paying for data syncing. That's like a thing where people pay to sync the data and they say, oh, actually I need to have this available on all my devices. You can store that data. You can let the people use the application even before signing up for an account or even choosing to sync it to a server somewhere. ([Time 0:01:41](https://share.snipd.com/snip/b07098e1-eb14-4c72-bc6e-db241b64d592)) - **Try Before You Buy** - Local storage enables offline app usage and lets users try before committing to an account or data syncing. - This approach enhances user experience and encourages adoption. Transcript: Scott Tolinski Yeah, another thing too often that like, I think you see this a lot more in native apps, which is something that people might be doing on the web more and more these days is letting you use The thing before signing up for an account or even maybe paying for data syncing. That's like a thing where people pay to sync the data and they say, oh, actually I need to have this available on all my devices. You can store that data. You can let the people use the application even before signing up for an account or even choosing to sync it to a server somewhere. And that's just like straight up usage of your application. If it is like a to-do app you're physically saving all the mutations and doing everything in the local data and in that same regard you might be saving that data locally from the server Into local storage or into your index DB or local storage or literally anything so that way you can access it faster because if the data is already on the client, you don't need to go to The server to get it. ([Time 0:02:50](https://share.snipd.com/snip/6d6623f7-c780-4489-9e90-d53533eee20f)) - **Privacy-Focused Local Storage** - Leverage local storage for privacy-sensitive data, like images, to avoid unnecessary uploads to external services. - This builds trust with users concerned about data privacy. Transcript: Wes Bos It can even just be a privacy thing. So I built a background removal tool. And the thing with people's photos is they don't want to upload them to some random sketchy service that they're going to have. So this background removal tool will just do it entirely in the browser. And the thing about that is if you refresh the page, they're gone. So you can stick those files and stick all the data related to that in the browser in one of the places that we're going to be talking about. And that way, when you come back and refresh the page or even like I was on JS Bench the other day writing some benchmark tests for JavaScript and I like refresh the page before I had like Saved it or TypeScript Playground is another good example. Before I've saved it, right? Before it's in their database, if they even save that in their database, then it's gone. So it's nice to just persist it locally in the browser before you even have decided to send that to a server. ([Time 0:03:51](https://share.snipd.com/snip/8f733d42-12ed-4bf8-a61e-79c8a2f7454a)) - **Persisting User Progress** - Use local storage to preserve user progress in forms, drafts, or shopping carts, preventing frustration from lost data. - This improves user experience and reduces bounce rates. Transcript: Scott Tolinski I think anytime, like you said, anytime that you would expect your application to, if you hit the refresh button, for it to remain in the same state as when you left off, you're filling Out a form. You're shopping at a store. You have a draft of a tweet. Those types of things, right? Anytime you want that state to persist is a perfect opportunity to save your users some headaches by putting that information in local data. Let me tell you, there is nothing more frustrating than filling out a big ass form and having the page refresh for some reason and having to start over. If you are doing job application things where they ask you to fill out every single one of your experiences or any of that stuff, you gotta have that data storing locally or something So that way the user isn't losing that. ([Time 0:04:53](https://share.snipd.com/snip/4931481f-87e3-4c22-8554-c5ea4b99d7eb)) - **Local Auth Tokens** - Authentication tokens, like JWTs, are often stored locally in cookies or local storage for seamless authorization. - This enables efficient client-server communication without repeated login prompts. Transcript: Scott Tolinski That drives me absolutely crazy as a user. And your users will be delighted for it. I'll tell you that. Another one is auth tokens. We don't often think about this, but anytime you log into anything, it's either storing it in a cookie or local storage typically, whether it's a session token or a JWT as an access token, Those types of things. These are stored locally on your client. Reason being is anytime you have a request to that server, you need that information there at the initial request. That way the server can be able to authenticate it as you go or authorize it. ([Time 0:05:43](https://share.snipd.com/snip/3e70f7a2-c444-4006-b5b8-3f9fdace3fb1)) - **Cookie Usage** - Use cookies for small pieces of data like language settings or session IDs. - Limit cookie use due to size restrictions and potential privacy concerns. Transcript: Wes Bos All right. So the first one is cookies. Storing data in your user's browser, you can throw them in cookies. There are HTTP cookies, which can only be set and read via the server and server requests. And then there are just regular cookies, which can be set and read via JavaScript as well. Cookies have a limit to how much data you can stick in them. So generally, cookies are only used for things like language settings, session IDs, just like identifiers and short little text settings for that specific user. ([Time 0:07:10](https://share.snipd.com/snip/2fcef580-2d13-4c6f-9597-8dc657f65543)) - **Local Storage for Objects** - Leverage local storage for simple string values or single objects by using JSON stringify and parse. - Remember to handle potential parsing errors from unexpected data types. Transcript: Scott Tolinski Yes. Next up is local storage. Local storage is often more used for single values, like a JWT, which could then be encoded, decoded, those types of things, or a simple string value. Or you might use a local storage for preferences, anything that you need to just save. Again, typically just a single string, save it, retrieve it, those types of deals. Wes Bos Yeah, local storage is, you can fit a lot in there. But the thing about local storage is that it's only text, right? It's key value store. So if you are trying to store something that is not text, you have to convert that to text. So if it's an object, you JSON stringify it. If it's an image, you can store images in local storage by converting to base64. It's probably not the best bet, but it's a really simple API where you can simply just say local storage.setItem, local storage.getItem. You can pull it out. The only thing that gets me sometimes is I'll pull something out of local storage and assume it's an object and assume you can JSON parse it. But it's not, not always the case, right? Sometimes you accidentally set undefined and then try to JSON parse undefined and you're in trouble. I'm ([Time 0:07:48](https://share.snipd.com/snip/d57b4c74-52da-45ab-abac-ebbd735019d0)) - **IndexedDB for Structured Data** - Consider IndexedDB for structured data storage instead of cookies or local storage when dealing with multiple values. - Scott often prefers IndexedDB for this purpose. Transcript: Scott Tolinski Almost always saving things in cookies over local storage for no particular reason other than I just do. But nowadays if I'm storing data like beyond single values or whatever, I'm using index DB typically. There's also session storage. So session storage, just like local storage. However, if you close the browser, you close the tab, that's the end of the session, and it goes away. I've never used session storage. I'm going to be straight up about that. I just haven't hit a situation where I needed session storage, but I'm sure there's plenty of reasons to use it. ([Time 0:09:01](https://share.snipd.com/snip/3d149486-286f-4a01-967b-083343dc26bd)) - **Session Storage for Privacy** - Use session storage to store temporary data that should be deleted when the tab or browser closes. - This protects user privacy on shared devices, especially useful for sensitive forms. Transcript: Wes Bos I think a good example of session storage would be, you were just talking about like you're filling out a form or a job application. You want to be able to refresh the page and that data to persist. Cessna storage will persist in the same tab if you refresh the page. It'll not if you open up a secondary tab. And that's really important if you, somebody is potentially on a shared computer. So you imagine a job application, somebody goes to apply for a job, they fill out the thing, maybe they don't finish it, and then they close the tab. If you put that in local storage, somebody else comes around and opens up the same website, then there's a bit of a privacy issue because now you're sharing your data between users of The same device. Whereas session storage would, as long as they close the tab, you will, you'll be fine. It's cleaned up. Yeah, ([Time 0:09:37](https://share.snipd.com/snip/d2303bf6-aaf2-4c06-8cce-4b2de4f6d286)) - **Using Dexie.js with IndexedDB** - Simplify IndexedDB interactions with Dexie.js, a library offering a user-friendly API and React/Svelte hooks. - This makes managing structured data in IndexedDB easier. Transcript: Scott Tolinski That makes way too much sense. So thank you for that. Next up is indexed DB, which like a lot of people, I think, they say that it's hard to work with. And honestly, I've used it just, you know, raw, straight up API, and I didn't find it to be that awful. It's not like the most fun API. It's not as simple as just get set, whatever. However, I do use Dexy quite a bit. Dexy is a small library on top of IndexDB. And it's basically just giving you a nice little API for creating, getting, updating data. And, um, you know, you have to do a little bit of setup, but it's more like working with things that you're typical, like normal databases that you work with. And for the most part, I found Dexy to be a nice to work in and pretty much anytime I need to store structured data, uh, an object of data, I'm not picking cookies or local storage. I'm picking IndexedDB, obviously, because that's what it's made for. Wes Bos Yeah, you can't query local storage, right? You can simply just check if a key is there or not, whereas IndexedDB is a database, and you can query it and filter and do all the stuff you're used to. And I picked up DexyJS for that background removal project I did, both to store files, which the browser also has file storage. We did a whole episode on that. But you can also just store blobs of data in IndexDB. And the cool thing about it is it has React hooks and Svelte hooks so that as long as you save it to IndexDB, your application is reactive and it's your whole state store. ([Time 0:10:32](https://share.snipd.com/snip/9c39f6e2-9013-416b-b085-d4d777b542c3)) - **BYOJS Storage Library** - Explore Kyle Simpson's BYOJS storage library for a unified key-value API across various storage mechanisms. - This simplifies working with different storage types. Transcript: Scott Tolinski I want to introduce you to a library from Kyle Simpson of You Don't Know JavaScript fame. He has a library. He has a kind of a bunch of new packages called BYOJS that are all kind of cool. And one of these is a storage package called storage, BYOJS.dev forward slash storage. And the stated goal of this project is to have a simple key value storage API for all of the storage mechanisms. So you have a basic git and set, and the only difference is where you import those from. So you import it from IDB for indexed DB, from local storage or session storage cookie, OPFS, which is the private file system. And so, yeah, basically it just gives you the same API to work with in all of this stuff. And I thought this was a really neat API that you don't really hear a lot of people talking about. ([Time 0:12:14](https://share.snipd.com/snip/2e3d835e-9dc2-433a-a322-c9e257ff6f44)) - **Faster Loading with Local Data** - Local data enables faster initial page loads by rendering UI first and fetching server data in the background. - This improves user experience, especially in client-side rendered applications. Transcript: Scott Tolinski Yes. So that's all great, right? You can store data in any of those numbers of ways. So, you know, and primarily when you're doing this stuff, especially in applications that are loading this data, you can think of a lot of the times that this data, since it's living On the client, is a use case for not waiting for a long server response. Because if the data is living on the client, right, you don't necessarily always want to wait for the server to hit the database to do all the database stuff on the server before returning HTML. You want to get the client side HTML and JavaScript as fast as physically possible. Then the data is there. It doesn't take any time to read it from the local database. It's infinitesimally small to load from a local database compared to loading from a database on a server and building the HTML. So you're doing a lot more client side rendering, which is one of the reasons why I've been talking about client side rendering more. It's that you're sending the information to the client, the client is then grabbing the data, loading it up, getting you all ready to go. And then occasionally, if you need it, in the background, you could be fetching the data from the database, that database process on your your server side database could be kicked off Right away. So that way, by the time that that comes back, you initially have data, you initially have a loading thing that's beyond a blank skeleton screen, and then the rest of the data can be filtered In in any sort of way. Now, you could have like a little syncing message to let people know data is coming in, or you can just pop it in, which might not be a great solution if you're getting your UI popping all Over the place. ([Time 0:16:54](https://share.snipd.com/snip/c3d479df-bb56-4cac-b72d-d93cc37de113)) - **Efficient Data Syncing** - Optimize data synchronization by sending only changed data (patch messages) instead of the entire dataset. - This reduces the size of sync messages and improves performance. Transcript: Scott Tolinski And one of the cooler things that many of these new libraries are doing is that instead of like the naive way, I've done it the naive way a whole bunch of times, if you need the sync, by the Way, there's plenty of application where you just save things locally, and that's it. That's definitely super valid. So you don't always need a sync. The naive way is just to send all the information every single time. And that's too much information to send every single time. But if you're not dealing with a ton of data, not a huge deal. But the more and more data you add to the system, the larger and larger those sync messages are going to be. So a lot of the things that the new platforms are doing is would be like patch messages. So it's only sending the data that's changed. So it's asking for what's changed since this version, oh, this has changed that way, that sync message becomes smaller every single not every single time, but it's smaller than it would Be if you're sending all the data, meaning that that trip becomes much less, meaning that you don't have that crazy pop in or anything like that, because it's not sending a massive bundle Of data that then needs to get updated into your local database. ([Time 0:20:00](https://share.snipd.com/snip/99d41312-0cc4-441f-a831-560acac6e83e))