Add a Login to Your Svelte Site With Auth0
with James Quick
How do you add a login to Jamstack sites? In this episode, James Quick will show us how to combine Svelte and Auth0 to create a members-only section!
Resources & Links
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
JASON: Hello, everybody, and welcome to another episode of Learn With Jason. Today on the show, we've got James Quick. What's up, James? How are you doing?
JAMES: What's going on, man? It's good to see you and hang out. I don't know if you know this, but I secretly wanted to be on this for a very long time.
JASON: Well, that's ‑‑ I mean, I'm flattered. I'm always happy to hang out with people. I'm happy to have you on here. I think this is gonna be a lot of fun. So, we are, let's see, we got ‑‑ we got a lot on the plate today. So, we can talk about that, but why don't we start by talking about you. Do you want to give us a little bit of background on yourself?
JAMES: Yeah. I don't even know ‑‑ I don't know where people start. I have a computer science degree. Started as a technical evangelist at Microsoft. Technical developer at FedEx. The week before Monday was my last day at Auth0. We already had this scheduled, so, I figured it would be good to go ahead and continue with a SvelteKit and Auth0 content. I joined PlanetScale literally Tuesday or Wednesday, I don't even know.
JASON: Today is Tuesday.
JAMES: So, literally yesterday joined.
JASON: It's one of those weeks.
JAMES: Yeah, it totally is. Anyway, I'll be ramping up there and creating more content. I'll stream after this on the brand‑new PlanetScale Twitch channel. Hopefully be able to take a bit of your audience over there.
JASON: Yeah, you're gonna marathon it a little bit. Everybody stay tuned. We'll go and raid PlanetScale today. So, PlanetScale is exciting. We're not gonna talk about PlanetScale today, but for folx who want to learn about it, you can go watch the next stream. In this stream, we're gonna talk about Svelte, specifically SvelteKit.
JASON: And Auth0. So, let's start by talking a little bit about Auth0. So, what is it? What problem does it solve?
JASON: Yeah, I think, you know, authentication is one of those things that spooks people easily. I know that it's really intimidating if you've never done it before to be staring down, like, okay, I got to figure out how am I gonna let somebody, like, create an account and log in? And then I got to be able to handle password resets and I got to do all this other security stuff. If you've never built these types of systems before, it gets really intimidating. I've tried to build, like, hash password tables and password recovery and things like that. You know, I managed to pull it off, but I don't think it was good. So, it's nice to ‑‑ it is definitely nice to have a way to just kind of have that stuff handled for you.
JASON: Drop‑in solutions are always really nice, especially with stuff like auth where it's effectively the same thing. You're not reinventing wheels. Most businesses don't have special cases in terms of what they're gonna do with auth. So, yeah, Auth0, I've used it on a couple projects. It's nice. It's handy. I'm excited to work with it again because I haven't looked at it in a while. And then the other thing we're gonna do, we're gonna be working a little bit with SvelteKit. I've done a bit with SvelteKit. I did a stream a while back where I had a guest had something come up, so I just kind of spent the time experimenting with SvelteKit and seeing how it felt. I really liked it. It's a powerful, you know, it's a powerful bit of technology and it feels good to use. So, what has you excited about it? Like why is SvelteKit something that you're pumped about?
JASON: Yeah, I think, you know, the interesting thing that you're touching on here is the sort of level of opinions that your framework has, and I think that something that I've heard Rich Harris say, the creator of Svelte, is your framework should have an opinion on the things that you do every single day. So, if you're writing a Svelte app, you're gonna need storage, you're gonna need animation, you're gonna need these things that you do ‑‑ virtually every web app needs a little bit of this stuff, and I think that, you know, React has sort of taken the other approach where React is more of we're gonna give you primitives and we're not gonna be prescriptive about the way that you solve problems. So I think there is a sort of a gradient, right? Like what type of control, what fine grain of control are you looking for? And I think that what we're finding is that a lot of people really do like the ‑‑ they like opinionated frameworks. This was one of the strengths of Angular. I think that's why a lot of people used it back in the day, when you put put Angular on a project, it had a lot of opinions, you did things in the Angular way. It was really predictable. If you look at the code base of any company, it's really, really similar. That's also its downfall, why people get grumpy about Angular because you have to do so much boilerplate to make it do what you want. Svelte is an interesting spot where it doesn't feel like a ton of boilerplate, but it has that similar level of opinions about how you do common things. Yeah, so, okay ‑‑ so, oh, we got some ‑‑
JASON: Thank you for the sub. I saw Ben subbed earlier. Thank you, Ben, for the sub. I think you're over a year now, which is wild. Thank you so much for sticking with me for this long.
JASON: And also I saw somebody calling out my new backdrop. Look at it. Look how nice it is. I'm just gonna get out of the way. I'm so happy about it. Oh, boy, I just kicked everything. Oh, boy.
JAMES: I've got some ‑‑
JASON: Everybody pretend that's not happening.
JAMES: I've got some updating to do. I just moved my desk around. You can see it's kind of bare back there. I have a similar idea. A couple of shelves. I want more developer hats. I want to have those on display and a Harry Potter wand. Keep an eye out for that in the next couple of weeks.
JASON: That's great. I see you joking about the plants in there. (Laughter) Yeah, I definitely have already had to chase Marisa out of here. She came in with a plant and I was like, no, it'll die. There's not enough sunlight in here. Okay. So, here's what we gotta do. Let's ‑‑ why don't we just actually switch over and actually start coding. I feel like we could probably talk in the abstract about this stuff for a long time, but it'll be more fun to show people how this stuff works. So, before we get into it, you can always find on the homepage of the site, we have live captioning. So, we've got Jordan with us today from White Coat Captioning. Helping us make this possible. Helping make this show more accessible, which I really appreciate. Then we've got the sponsors, Netlify, Fauna and Auth0, all kicking in to make the show, you know, make it possible to get the captioning, which is really nice for me. We also, while you're clicking on things on the internet, we are hanging out with James today. So, make sure you go give him a follow on Twitter. And this, I think, is an article. So, this is the article that we're gonna kind of use as a base here, right? To get started. We're gonna make some modifications here. Because this is not using SvelteKit. So, how about this? At this point, we are kind of looking at the raw components. What should I do first?
JAMES: Well, I think, if I remember correctly, the first thing in the article is to actually register the app inside of the dashboard. So, we can kind of scroll through that as we go. They have a little description of what it's gonna be. We talked about prerecks before, have Node installed in a browser, no surprise there, and create an Auth0. When you do that, there are a couple of credentials that come with it that we'll need to add into the application code itself to be able to configure the SDK.
JASON: How do you ‑‑ here's a login button.
JAMES: I feel like that would be great feedback.
JASON: Here's ‑‑ all right. So, I'm authorizing Auth0. It's taking me back. And, all right, we're in manage.Auth0. Okay.
JAMES: Did you do the, like, Gatsby swag store? Did it use Auth0?
JASON: It did, yeah.
JAMES: That's what I thought. Okay. That was a cool use case.
JASON: Yeah, that was a fun one. You can find that over at ‑‑ or what is it? It's store.gatsbyjs.com, I think, assuming it's still up. Is it at org? There it is.
JASON: This is the Gatsby store. That's an Auth0 project. And if you want to see how it works, down here at the bottom, you can find the source code for it. That's a full‑fledged project you can go and look at a little more production. It does a bunch of fun stuff in there.
JAMES: I love seeing good examples like that. By the way, the last thing on the bottom of that page, if you go back, is this the way on the ‑‑ yeah, is this the way of gating to say, like, you want to have something registered in your store to give away but not let people buy, so it's exclusive, so you make it $1,000 apiece? Is that what that's for?
JASON: That's a great question. I assume so. It's been a long time since I've done anything with Gatsby, so I'm assuming, yeah, this is a giveaway they don't want people to buy straight‑up.
JAMES: Several like that that were like $1,000 for a t‑shirt. I'm like, that's not what this is made for.
JASON: All right. So, I have a bunch of applications. I have no idea what any of them are. I'm actually gonna pull this off screen real quick, just in case I've got some stuff I'm not supposed to show. Oh, no, these are all, like, demo apps. That's fine.
JAMES: Yeah, it's probably okay, as long as you don't go to, like, your user tab or anything.
JAMES: Also, the client ID, you can see those on your screen, just underneath the panel that you're on. Those are fine to share. You don't need to go out of your way to do it.
JASON: Those are public, right?
JAMES: Yeah, they're just the unique over for the app itself. There is nothing inherently secret about it.
JASON: Got it.
JAMES: What you've done is clicked on "create an application." This is the panel that comes up. You can give it an arbitrary name. It doesn't really matter. Whatever name you think works best. The behind the scenes detail gets into the way that Auth2 work. At Auth0, it was interesting to learn the details about those things. From a person who doesn't work at an identity company, most of us don't really care that much. But the implication of that is that those things get implemented slightly differently based on the type of application you're working on. So, native app versus a regular single‑page app versus a regular web app. And interestingly, things like Next.js fall into the regular web app category instead of SPA, even though it's built on top of React. That's because it has a more server‑side component to it. The big difference you'll hear in talks that I give about identity and stuff, specifically with these workflows is what type of application can, quote, unquote, keep a secret? So, with a regular web app, because you're able to run in the Next.js perspective, because you're able to run code in a serverless function that runs ironically on a server, you have access to private credentials through your environment variables that never get shipped or shared in in the browser. So, in that sense, they can keep a secret. But regular React, Angular, Svelte, Vue, cannot keep a secret. In this case, we're going to choose single‑page web app. A little additional context. There is a Next.js specific SDK. There is not a SvelteKit specific SDK. They have functions that can run on the server, there is no, like, SDK to really integrate that stuff seamlessly. So, we basically in this case are gonna treat it like a regular single‑page app with Svelte.
JASON: Okay. Okay. Do we have Svelte?
JAMES: We do not, I don't think.
JAMES: Yep. You could click on that for the getting started just to kind of see what's there, but we'll follow the details that are in the post, but it'll be fairly similar.
JAMES: Somebody commented in the chat, I can keep a secret... most of the time. Fair enough.
JASON: Don't you lie to me, chat. I know you steal my secrets.
JAMES: One of the things about not having a specific SDK, there's not a specific SDK for Vue and for Svelte. There's one for Angular, React and Next, and this is where, like, community feedback comes into play. So, if people, like, really, really said, hey, we absolutely need Svelte or SvelteKit or Vue or whatever, that's the kind of thing people could comment and leave that feedback, to see if that could be something that gets prioritized in the future.
JASON: Gotcha. Gotcha. Okay. So, I have, let's see, we've got our app. We created the app. And then this, I think, is gonna be different. Now, do I need to ‑‑ oh, wait, hold on. Okay. So, I need to go into the settings.
JASON: And then I need to set up some stuff here.
JAMES: Yep. And we'll ‑‑ because SvelteKit, when we set that up, will run by default at port 3,000, we'll change what you're about to copy to 3,000, but you can go ahead and copy it. So, in the settings tab, there should be three spots to paste that in. A little bit further. So, the allowed callback URLs.
JASON: That's gonna be 3,000.
JASON: And then we're going to, I assume these ‑‑
JAMES: Log out. Yep. And web origins. And the reason the ‑‑ yeah, I don't know the ‑‑ I've never used the actual origin one. I'm not sure what that would be for, but anyway, I think we'd be fine regardless.
JAMES: So, what this is, really quickly, like, again, if people are interested in details, open ID connect are the two standards for implementing authentication. What happens is from our application, we're basically going to redirect the user over to Auth0 and Auth0 is going to redirect the user back. We're just telling Auth0 where users will come from and where they can safely send people back to.
JASON: Got it.
JAMES: And this is ‑‑ I was gonna send you this link. You're already on top of it for setting up the next ‑‑ or SvelteKit app.
JASON: All right. So, we are gonna do svelte@next and we're gonna call this lwj‑Auth0‑SvelteKit. Okay. So, it's gonna install the package. Great. Beta software. Do we want skeleton or demo?
JAMES: Just the skeleton. Have code that we don't need. Skeleton will be pretty bare. I don't think the tutorial uses Typescript, so, we're going to skip that for the time being.
JASON: I will use prettier because that's nice. Great. Okay.
JAMES: And now you can follow those instructions, open it in VS Code, I assume, do an install, and then we can run what's there.
JASON: Great. Okay. So, I'm gonna git init. We can probably pub this thing, right? Git add everything. And then we'll git commit. All right. And then we'll create a repo at learnwithjason/lwj‑auth0‑sveltekit.
JAMES: We're already getting some heckling in the chat about not using Typescript.
JASON: Always. Yeah, we'll definitely do a little. Typescript has taken off. I feel like there was a long time ‑‑ did I not push the ‑‑ oh, I didn't push the button. Okay. Now we've got that. I can git push. We'll set the upstream to origin main. All right. Now that I've got that, I can Netlify init this thing. And I'm just using the Netlify CLI thing. We'll get this thing published. Put it on my account.
JAMES: I have not done the Netlify CLI. Is that new?
JASON: It's been around for so long and we just don't tell anybody about it. Here's the thing, we did a launch on it a little over a year ago. At the time we launched it, it was fine but it didn't, like, quite do all the things we needed it to do and people on, like, different frameworks would have issues, and so we just kind of didn't ‑‑ we didn't get too into telling people about it because we didn't want people to get frustrated. But then we've been steadily making progress, and it's been, like, really ‑‑ it's really good now. We just, you know, still haven't told anybody yet.
JAMES: Yeah. Is there ‑‑ can you stream log messages with the CLI?
JASON: I mean, you just develop locally, right? So I think you might ‑‑
JAMES: Well, I mean, if I have something going wrong on my deployed build and I just want to stream, like, watch those as they come in.
JASON: Let's see. Can you ‑‑
JAMES: And if not, then my unsolicited request would be to be able to do that. Because right now, every time I have a function and an error, I have to log into the dashboard and see if it's in that recent, like, snapshot of logs. I also could be more official and set up log bracket or something for better stuff, but I just haven't done that.
JASON: Yeah. No, that's ‑‑ that is a good point. So, this will open in the wrong window. Geeze. Okay. Let's put this over here.
JAMES: Now one thing ‑‑ one thing I don't know, so, there's extension, I think, for deploying SvelteKit to Netlify. I don't think just the regular build or whatever, so, we can come back to that. Yeah, the adapters. And maybe try to get that configured. I've never done it before, but we can maybe try to get it configured after the fact.
JASON: Cool. Looks ‑‑ all I have to do is this? Okay. Let's try. Let's try. NPM install this one. And then I gotta get this bit here, put it in Svelte config. Actually open this up. Here's our Svelte config.
JAMES: The chat is confirming it should be that easy using the adapter.
JASON: Nice. So, we just need to drop this in here. Wow, I can't. There we go. To there. Jesus. All right. (Laughter) All right. So, that should fix it. Export default config. Good, good, good, good. All right. So, then if I git commit everything and say fix, use the Netlify adapter, git push, then that should get this thing live. So, let's go and look.
JAMES: I'm glad you thought to do that. I didn't even think about ‑‑
JASON: Oh, you need to install it with the Next flag?
JAMES: Install which piece?
JASON: I think I need to install it with the @Nextflag.
JAMES: That's what the chat is saying, too.
JASON: Yeah, I missed that part. What's up, Ben and friends? Welcome, welcome, welcome. We are doing some ‑‑ we are doing some SvelteKit. We're doing some Auth0. Right now, we are trying to get this adapter up and playing nicely. I'm very excited about this. This one's gonna work. Here we go. This is the one.
JAMES: Those are, like, such dangerous words. I can't tell you how many times I've done something live, all right, this is the one, and it's like 50 times.
JASON: We did it.
JAMES: Something's happening, so that's good.
JASON: Yeah. All right. Now we've got our SvelteKit site. There we go. SvelteKit, running, operating, we got ourselves a site.
JASON: So, now what we can do is ‑‑ so, if I run this, do I need any, like, serverless functions or anything to be running here?
JAMES: We won't.
JAMES: So, maybe that's one distinction we should clarify. So Svelte is regular ‑‑ people get very specific about, like, compiler versus framework. We'll throw it into the general framework category of Angular, Vue, Svelte. SvelteKit is basically the equivalent of what Next.js is for React, Next.js is for Vue. Where you have like this server‑side of being able to run the serverless functions we talked about a little bit earlier. In this case, we're not doing anything with the server side. Keeping all of this on the front end. It's going to be like a regular SPA app using Vue. The SvelteKit, the new compiler is built with ES Build which Vite is on top of. Uses it under the hood, is that right? So, it makes it so much faster. I was having this struggle earlier when I was building something with regular Svelte. If I, like, added something to a to‑do thing and it showed and I updated the code and refreshed, it got rid of all the previous stuff I had entered. Versus this does in place hot module replacement ‑‑
JASON: Actual context. Yeah. That's nice. That's really nice.
JAMES: Yeah, so, I figured it's faster, it's nicer once you get it set up. If we wanted to, which we probably won't get to, it's got page or route‑based ‑‑ page ‑‑ what's it called? Based routing.
JASON: File‑based routing.
JAMES: File‑based routing. Thank you. You add a file in a specific location and it host it is as a route for you. Okay. We should be at the install the SDK part. So, if you want to copy that line and throw that package in there. This, again, is the generic SPA JS framework. This is what you would use for Svelte in this case or Vue. If you were doing Angular or Next or React, there are specific SDKs for those.
JASON: Okay. I want to create a store.js. All right.
JASON: And then inside of that ‑‑
JAMES: You can kind of copy it in there and we can talk through it, if you want.
JASON: Yeah, yeah, yeah, why don't you run us through what this is actually doing.
JAMES: Yeah, so mentioned really briefly earlier, stores are probably one of my favorite aspects of Svelte. So, if you look at, like, React context API, you can do it and it works pretty well, but it's a little tricky to set up. Stores is what you call services in Angular. Which follow the singleton pattern. It's basically any data that you need to either update or read, you have it in this central spot so that you can access that information and update that information in and from different components. So, that's basically what we're trying to accomplish here.
JAMES: Is we want to track a couple of pieces of information about the user. Are they authenticated? What the user is. Whether the pop‑up is open. And then if there is some sort of error. And so what we do is import the writable from Svelte Store and then we initialize those properties, those four, as being writable. What that means is from different components, as long as we export these, they can subscribe to that data, they can listen for changes to that data, they can also update that data, which is pretty nice.
JAMES: And then the derived is relatively new for me, but I think I can explain it. Derived is saying, like, I want to basically use properties that are writable and combine or gain some sort of insight or derive some sort of insight from those properties and then return some sort of specific value. So, in this case, it is grabbing all the tasks that are associated with the user's email that's logged in, if the user is logged in.
JAMES: So, it's dependent upon properties that are used above or defined above as writable and then you derive the user tasks from those different pieces of information.
JASON: Gotcha. Yeah, this is ‑‑ this is cool.
JAMES: So, for additional context, like, in the React perspective, all that information is authenticated user and a couple of other things is basically what becomes a provider inside of React. Like the SDK basically does this for you in React. Now we're just kind of setting up the boilerplate in Svelte for us.
JASON: Gotcha. Makes sense. Okay. So, now, we want to create a new file. And this one's gonna live at ‑‑
JAMES: And you can ‑‑
JASON: Is it the route auth config here?
JAMES: You can. When I was doing this earlier, I had some issue importing. I'm not sure why. We can give it a shot, and if we have an issue with the importing of these settings, we'll just copy those in directly because they're not private.
JASON: Okay. All right. So, our domain, that's gonna be the local host 3,000, right?
JAMES: It will not actually. In this case, it's the Auth0 domain. So ‑‑
JASON: Ah, gotcha.
JAMES: Which is actually a great ‑‑ a great callout here. So, the domain in Auth0 is associated with your tenant. So, a tenant is basically a grouping of applications in Auth0. You can see in the, like, top‑left of your frame, there is J Lengstorf, that's going to be part of the domain. At the bottom of your screen now, you can see the property domain under ‑‑ it's gonna be that tenant name, which is J length store and .Auth0.com. If you're in a different region, it might be .eu, et cetera, but in this case, it's just .Auth0.com.
JASON: Good? All right. This is gonna let me ‑‑ this will be how we log in. This is a client ID so that we know that this app actually knows, like, what this app is. Because this would be the same for all of our apps. This is just saying, like, we're logging in to lwj.
JAMES: One clarification, it would be the same for all the apps that are still in that same tenant. You can have different tenants that are different groupings of applications. Assuming you're staying in the same tenant, it would be all the apps under that tenant.
JASON: All right. It's wanting me to git ignore this, which seems ‑‑
JAMES: It's unnecessary. So, these are actually, like, I might send them a message and say you don't have to. They kind of imply here you don't want to mistakenly push your details to a public repo. It's probably good to have them from a configuration standpoint and environment variables, but there is absolutely nothing wrong with checking these in. Neither of these pieces of information is private. So, you can skip that for now if you want.
JASON: Gotcha. We can also ‑‑ let me make this quick change here. I'm gonna keep the ‑‑ so, if we run this through ‑‑
JAMES: Run it through Netlify dev.
JASON: Then we can set environment variables.
JAMES: Cool. And make sure those are comma separated.
JASON: Comma separated. Gotcha.
JAMES: I wonder, does it make that clear in there? It has a little piece of text right under, yeah. Comma‑separated list.
JASON: It was like you are broken. Okay. There we go.
JAMES: So, what you're going to do, you're talking about going ahead and creating your environment variables in Netlify, connecting this site that we're running locally to Netlify.
JASON: Yeah, I can go Netlify env: set and then we'll say Auth0_DOMAIN.
JAMES: I love this. I need to start using the CLI. That is dope.
JASON: I can do the same thing, but will do Auth0 client ID. And we'll put in our client ID here.
JAMES: Love this.
JASON: All right. So, those are now set. And then when we run, like, if we start this server, it'll pull in those env and then run the site using those. So, now both for our builds and for local dev, we've got these set. So, we can actually ‑‑
JAMES: Does Netlify have contextual environment variables, like, for different for dev, prod, that sort of stuff?
JASON: There are some plug‑ins for that. It's not, like, straight‑up supported. You can make it work, but ‑‑
JASON: That's something that we've been talking about on, like, how do we make this all better. So I think it's on the roadmap, for sure.
JASON: Let's ‑‑
JAMES: That would be awesome.
JASON: I do have one concern that this is a front end framework, right? So, is it gonna pull process env or do I need to do a Svelte prefix for env?
JAMES: Great question. There probably is a prefix. Let me ‑‑
JASON: Let's go check it.
JAMES: Yeah, I'll search with you.
JASON: Let's go to environment variables. Where you at?
JAMES: It looks like Vite ‑‑ excuse me Vite. I've already gotten yelled at about that many times. Vite public is the prefix. See if you can find something that confirms that.
JASON: Let's go to the deploy settings. We'll go to environment. And then I can say. So, just Vite public like that?
JAMES: I believe so.
JASON: Okay. So, we'll save those. And then in here, then when we run those, they'll pull in, and then I guess what we can do is come back here and we'll just do, like, a process.env.Vite_ public_Auth0_domain. And then I can copy all of this. All right. So, theoretically speaking, that should give us our environment variables. So, let's ‑‑ I mean, we're not at a point where we can actually test that yet, so we probably need to go a little bit further here. Auth service, right?
JAMES: Yep. And this is just another ‑‑ like if there was an SDK, this would be done for it. Since there is not a specific Svelte SDK, we're, again, kind of exposing those functions and pieces of information in the service that we want is basically ‑‑ basically what we're doing.
JASON: Okay. I'm just gonna copy‑paste this instead of manually typing it out. Let's run through what it does.
JAMES: So, we've got create client, which initializes the Auth0 client. You will ‑‑ it pulls in the properties from the auth config like you were just looking at. I think you updated the path correctly. That's good.
JASON: I did, yeah.
JAMES: And I think you also ‑‑
JASON: Oh, we got a frozen James.
JAMES: Have to add the .js. Oh, hello?
JASON: Yeah, you're back. That makes sense. So, yeah, I think that's a Vite thing, right? We have to include the file extensions.
JASON: Okay. So, now we've got create client. We've got log in with pop‑up. Now, neither of these are used. So are we ‑‑ oh, I just, like, stopped copy‑pasting down here.
JAMES: And then you end up exporting that last object at the end.
JASON: Got it. Got it. Got it. Okay. Cool. Auth. Yeah, all right. Okay. So, now that we've got all those pieces ‑‑ so, basically what we've done here is we're creating a client. This client uses the Auth0 client, which comes out of this SPA sjs. Sends in our domain and client ID. That's what's gonna allow us to do all the login things. Log in with pop‑up. This pop‑up open is our store. So, we're updating our store to be true.
JAMES: It will, yeah.
JASON: And then we run the login with pop‑up function, which looks like it just comes out of the ‑‑
JAMES: The SDK. Or it just comes from the client, yeah. From the client SDK.
JASON: Okay. And then the user, that's their store. So, we're setting that to be the value of the Auth0 user. And then we set is authenticated to true, right?
JASON: And then we close the pop‑up.
JAMES: Yep. And notice the ‑‑ we're using the set there for pop‑up open and user and is authenticated, because those are writable pieces from the store. So, because you have to call the setter, that basically allows the store to then broadcast, hey, things have changed for anyone that's actually subscribed to changes with that data.
JASON: Yeah. And that's, like, the derived, right? That will notified the derived state, hey, we've got a user now. You can go get the tasks for that user.
JASON: That's cool. I mean, this feels very nice. Like I like ‑‑ I like this approach. It feels good. It looks, you know, none of this was, like, wait, hold on, what happened? Which I think that's always good when you're looking at a new API. You know, the more advanced concepts. State is an advanced concept. You're trying to move around data between files, and that's ‑‑ that is not necessarily, like, the most approachable thing to do. So, the fact that we can read this and it's kind of like, okay, I get what's happening here. Like this makes sense. I have this. It's writable. I'm gonna set its value to true. You know, we can get there.
JASON: So, great. All right. So, next ‑‑
JAMES: Now it's just kind of getting into ‑‑ mainly kind of to‑do list, boilerplate stuff. Again, we'll copy these snippets in, but we'll talk about them along the way, I think.
JASON: Okay. So, I'm gonna create a new folder called "components."
JASON: And in components, we're gonna create those task item.Svelte, is that right?
JASON: Okay. So, there's our task item. I'm going to grab out this, if I can. There we go.
JAMES: We'll have to make sure we update the imports and stuff again, since we're changing this to SvelteKit.
JASON: So, we're going up and then store.js. That makes sense. All right. So, we've got those tasks. We've got some styles. And then we've got our setup here. Anything else I need to change in here?
JAMES: I don't think so. One thing, we may have overlooked this. I don't know if we just haven't gotten there yet or not. The demo uses Bootstrap. If we were doing it for real, we'd probably do it a little bit better. On the article, scroll up a little bit. I think it was already ‑‑ let's just make sure. A little HTML? Maybe not. Maybe it's further down. Okay. Maybe we haven't gotten there yet.
JASON: Okay. So, here's our task list. And so this, let's see. We get our tasks. We have a single task. We check whether or not it is actually checked. We have the ability to show it. So, we do a list item with an input that's a check box. And we're updating checked on whether or not our input is checked.
JASON: And then when we change it, we check to see whether or not it is done. Okay. All right. That makes sense to me.
JAMES: And at the top of that page, we imported the writable stuff from the store. The tasks. So, this component will actually receive a task, like, passed into itself as props. The way you do that in Svelte and SvelteKit is line number 3, which is you export a variable. So, we're exporting tasks with a default value of empty object. That means that's basically a prop coming into this component. So, the task list thing is gonna want to take each task, pass it to this task item component. But above that, we import the tasks from the store, and then we can then use those in line 18 to do that set again. So, we make some changes to the task by updating that one task, and then we go ahead and update the tasks that are stored in the store. So, if you can imagine, once we have a component ‑‑ once we have the parent component of this that's the list, it will then trigger a re‑rendered because it will be subscribed to the changes to that data.
JASON: Gotcha. Okay. That makes sense. All right. Welcome, Alex and friends. We are getting into some SvelteKit here. So, we're trying to build out a SvelteKit app that's a to‑do list that uses Auth0 for auth so that you have a user login and then you track your tasks based on the user that you are. So, let's see. Building the task list page. Here is our Bootstrap stuff.
JAMES: There it is.
JASON: This is going to go into public index, but I think we'll put this in routes, right?
JAMES: It will go into the app HTML. The parent default HTML in this case ‑‑
JASON: I'm going to take this. We're gonna update the head.
JAMES: I think I would probably leave everything except for just the actual Bootstrap import. So, like, the 4th line. Yeah. You can just put that right below the Svelte head thing or right above it. Yeah.
JAMES: Did we break anything? Why is that tag not happy at the top?
JASON: It says: Documents must have a title element.
JAMES: Did we get rid of the title?
JASON: I don't think it had one.
JAMES: Huh. Okay. Well, I guess you can copy that one.
JASON: Drop that one in there and we'll say LWJ Svelte + Auth0.
JASON: Okay. Now it's happy. Look at it. Look how happy it is. It's a happy little app. We don't need global CSS. Now we're gonna get into ‑‑ what file is this? App.Svelte. This is gonna be our index, right?
JAMES: Yes. And we could ‑‑ so, there's the concept of the layout file in SvelteKit, which is kind of like the parent of all routes. Or you can actually sub ‑‑ you can nest it under route directories and just have it be a parent for a specific set of routes. Anyway, we could do this stuff. If we were actually doing multiple pages, probably what we would do is do all of this stuff in the__layout file which would be the wrapper for all the other files. Since we're on one page, we can throw this into the index.
JASON: Uh, let's ‑‑ so, you would do it like this? __layout. And then this will wrap everything. All right. And the reason that you do this, if I'm understanding correctly, is that we need this to be available. Oh, wait, I'm in the wrong place, right? This is definitely not the right thing.
JAMES: That's the right thing. Yeah. So, the reason ‑‑ the reason we would move the ‑‑ well, this file should be in routes, yes. Dustin was asking.
JASON: The layout goes in routes. We've got another frozen James. It is, like, 1 million degrees in my office right now. I am just a sweaty mess. Frozen Quick.
JASON: Oh, there you are. There you are.
JASON: So, we've got this ‑‑
JAMES: Yeah, chat, thank you. Yeah, so, you were asking about the reason to put this in the layout. So, the layout component when it's inside of the route of the routes directory will basically kind of wrap all of the ‑‑ all of the routes beneath it, which in this case is all the routes. So, all we're trying to do here is let Auth0 do its thing where it's gonna figure out if the user is logged in or not. We want that to be the very first thing that happens. When it figures it out, it will update the store and all the other components that are dependent upon properties from that store will then be able to render themselves correctly.
JASON: Got it. Okay. So, do I need to split this up a little bit? Because it looks like I've got some layout stuff, but then I have some index stuff. I'm wondering if I'm overcomplicating this.
JAMES: I think it's fine. Yeah, I think you can leave this here.
JAMES: So, so far ‑‑ and did we get all of the ‑‑ so, the task item on line 5, we'll need to update that import. I think we need to update all of those imports, actually. So, probably just two dots for each one of them instead of one. Back out to our routes directory and then the source directory, I believe.
JASON: Whoops. Okay. So, we've got 1, 2 there. Let me get the store.js needs to be up one. Okay. So, that ‑‑ those should all be correct.
JAMES: Looks good.
JASON: And then we haven't done any of this stuff. So, we've got ‑‑ here's our main application. So, we drop that underneath. So, this is just our basic styles. Hi guess I can ‑‑
JASON: Put this wherever I want, right?
JAMES: Yes. And that slot, by the way, is basically what, like, your children components would be in React. So, when we have those routes, the slot is basically the placeholder for the route components themselves.
JASON: Nice. Yeah, so, then we've got a bunch of markup here.
JAMES: A bunch of boilerplate. Yeah, we'll do a copy and paste in here. So, this, if we wanted to separate this out a little bit, probably what we would do is take, like, the nav bar portion of this. So, somewhere in there is a nav tag.
JASON: It feels like we kind of want, like, this, right?
JAMES: Yep. That's what I was gonna suggest.
JASON: And then I come back in here?
JAMES: In your index. Yep.
JASON: I'm missing a bunch of stuff, though. So, like, do I need to pull some of the things out of the layout into here or does the layout ‑‑ is it smart enough to, like, give me all of this stuff?
JAMES: So, you'll need to copy over line number 4, like the import of things from the store. So, that would be one.
JASON: Okay. So, we go ‑‑
JASON: Gotcha. I'm probably gonna need that task item over here, right?
JAMES: Yeah, because that will be what we use to actually display the task item.
JASON: Okay. There it is. Okay.
JAMES: And how are we looking? I think we're close.
JASON: Like this should ‑‑ we've got some unused imports here, but I think this should work, right? Let's run this thing.
JAMES: We shall see.
JASON: Fingers crossed.
JAMES: Live coding is the best.
JASON: Oh, it doesn't like something. It says: New task is not declared. All right. What are we missing?
JAMES: So, that would be the piece of state. So, in this thing, they didn't separate out, like, a form. So, copy over ‑‑
JASON: New task, Auth0 client, right? So, we need the new task. I have some regrets about trying to do this layout.
JAMES: I think it gives us a good reason to have more attention to detail about what the pieces are, though. So I think it's good.
JASON: Login is not defined, which means I got to get login out of here. On mount function login. All right.
JAMES: May end up being ‑‑
JASON: Do I just need to pull all of this stuff in?
JAMES: Unfortunately, login is gonna be used in two different places here. Because it's used in the nav bar, and then I think it's also in, like, the stuff that's not the nav bar. So, instead of, like, instead of having a separate function for that, what we could do is just, like, in the ‑‑ in the on click, just directly call that login with pop‑up. You can just copy those functions over, too.
JASON: I think I might just copy them over for the sake of speed here. So, what do we got now? It says: Add item is not defined. So, we'll just go and get all of these. And add item.
JAMES: Looks like that one. You can copy over the gen random, too.
JASON: Gen random?
JAMES: Yeah. Somebody said in the chat, the real question is, did you save? That is always ‑‑
JASON: Okay. Now I have saved.
JAMES: ‑‑ the real question.
JASON: And it doesn't like something. Unused CSS selector main application. Yeah, yeah, yeah. Okay. But I'm definitely getting issues here where index.Svelte, this should be saved. This is saved. So, what's not catching here?
JAMES: And we have ‑‑ are we on ‑‑ that is the right port.
JASON: Let's try this one more time. Okay. But how, though?
JAMES: I don't know. And there's still no issue in the terminal. It doesn't look like.
JASON: 404 not found. Okay, we got problems. It's, like, picking up weird stuff.
JASON: So, let's look at what's in here.
JAMES: Brittany's asking about port 3,000. So, yeah, when you run SvelteKit, by default, it's running at port 3,000, but then Netlify dev should abstract that and basically serve it to port 8888, which then allows Netlify dev to combine it with serverless functions, if it wants.
JASON: Okay. So, I just deleted all the cached files. So, let's run it again. Loaded function render. Started with SvelteKit. There we go. I don't know what that was. It was like it had cached something oddly.
JASON: So, here is ‑‑ wait, process is not defined. Uh‑oh. Process is not ‑‑
JAMES: Is that not how we actually get access to those variables?
JASON: I screwed something up. Let's go look. Here are our docs. And in the docs, I want to search ‑‑ what do you search? There is no research.
JAMES: So I think someone mentioned this earlier. It may be import.meta.env.name. Can someone ‑‑ yeah, Brittany ‑‑
JASON: Meta in front of the invariable. So, instead of process.env, you do import.meta.
JAMES: Seems like it. Which is interesting. Auth config. It's a Vite thing. Okay.
JAMES: I think so.
JASON: All right. Yolo. We'll try it.
JAMES: Also, mine ‑‑ we'll see if that works. Mine also mentioned import.meta.env. I don't know if we need the .env part, but we'll give it a shot.
JASON: It is import.meta.env. Multiple people are confirming that. So, here we go.
JASON: Let's try that one more time.
JAMES: Just think about without logging how long individually we would spend on errors without people to help us sometimes.
JASON: Brutal. Absolutely brutal. Okay. So, I missed the Auth0 client. So, we need that.
JAMES: Auth0 client. Rats, unfortunately, we need that from ‑‑ we need like the initialized version
JASON: onMount is not defined?
JAMES: You got to import onMount, too.
JASON: Gotcha. We're quickly approaching that I, like, overdid all of this. Okay. So, I can now ‑‑ now, look at this. We got Auth0. It's doing the thing so I can sign up.
JAMES: And this will ‑‑ by the way, this will be ‑‑ based on the tenant configurations. Oh, no.
JASON: Showing me Gatsby stuff.
JAMES: Background refresh.
JASON: That's not good. Let me try this one more time. Yeah, it really shouldn't be showing me Gatsby stuff.
JASON: Invalid request. Opened too many login dialogues. Something about the cookies.
JAMES: I wonder ‑‑ I think ‑‑ I think one thing we did was ‑‑ because we ‑‑ you copied over the onMount code but didn't delete it from the original one, I think it might be creating, like, two Auth0 clients.
JAMES: Is ‑‑ are we using ‑‑
JASON: Just delete all the things that we're not using and see how it goes. That's not used. This isn't used. Right?
JASON: Oh, and then this is supposed to go in here. That's why it's our unused thingy. So, then if I put this down here, then theoretically speaking ‑‑ now, this unexpected slot, I don't know if that's a thing we need to care about, but ‑‑
JAMES: I think I saw that earlier on mine, too, and I didn't know why.
JASON: Okay. So, I'm doing something wrong where it's, like, pulling from the wrong app here. Because I have this app, right? So, we've got our web origins.
JAMES: If you ‑‑ so, it may just ‑‑ did you run the Gatsby swag store from this tenant, do you know, in Auth0?
JASON: I think I did.
JAMES: So, whatever configurations were there for that tenant as a whole. Sorry, my dog. Whatever configurations you have with the tenant as a whole will then populate to this application. So, one thing we can do to maybe get this ‑‑
JASON: Maybe I just need ‑‑
JAMES: So, you can log in there, but probably the easier thing to do would just be to create a new tenant inside of Auth0.
JASON: Oh, I can create a new tenant?
JAMES: Yeah. If you hit that drop‑down where J Lengstorf is. You can just do this like "Jason test" or whatever.
JASON: Okay. So, let's go into ‑‑
JAMES: And then you'll need to create an app there. Copy over the local host stuff. Sevi. So, I've got one dog ‑‑ one dog is outside barking at another dog. The one that's in here with me hears that and is now missing out on all the fun. So...
JASON: There is nothing like being left out of barking at something.
JAMES: I feel like every time I get left out of that, I get very upset.
JASON: Local host 8888. All right. So, we'll do that one. That one. That one. That one. Okay. So, I've got all those.
JAMES: And then scroll ‑‑
JASON: And saved them.
JAMES: Yeah, scroll down and save.
JASON: I've got all the way up here. Here is my client ID. We've got app.Netlify.com. Let's get into this SvelteKit.
JAMES: Someone said: You're really used to writing Learn With Jason. I assume just because you wrote it fast.
JASON: I do type that many times a day. Let's see. So, then I've got that. And then my URL is this one. So, we'll throw this in here. Save it. All right. Let's try this one more time. So, I'm going to stop, restart ‑‑
JASON: The saddest dog. All right. Let's try this. This is gonna work. Log in. This is better. Okay. This is good. I would like to sign up. I'm gonna continue with Google. All right. Accept. There we go. All right. So, now I'm logged in.
JAMES: Thank you.
JASON: Good, good, good. Okay. So, we'll do some stuff.
JAMES: Do a boop.
JASON: Look at it go. These are all persisted, right? They are not persisted?
JAMES: They are, no ‑‑ so, this would be our missing piece here. So, I don't know, like, what the end goal would be in terms of time. They've got these filters in the article based on the user's email. But in this case, we don't have them persisted anywhere, so we don't really have a good way to actually see that. So, we could have this interact with, like, local storage. Then you could create some stuff, sign out, and sign back in with a different account to show that working. I don't know if we have time or want to go that far or want to try it out or we want to just kind of be good here with the fact that we actually have the login part working.
JASON: I think we might ‑‑ let's see, we've got maybe 25 minutes. So, we don't really have anywhere to, like, where would we put it? We'd put it in local storage or something?
JAMES: Yeah, I don't think we would go to an actual database.
JASON: Yeah, I mean, we could do that. One thing I'd love to figure out is I'm doing something wrong here, I'm doing an unexpected slot of default. Am I supposed to name these or something?
JAMES: Let me look that up, too. Because I'm not sure. I think I had that same warning earlier. Named slot is what ‑‑
JASON: So, it says ‑‑ minimized, minimized.
JAMES: Lily, come here.
JASON: Dev time warning. Huh, I don't know what it ‑‑ not really clear what it is.
JAMES: Is there ‑‑ I mean, if we're throwing out guesses, I was gonna say, add a name property to it. I don't know. Looks like actually, yeah, throw a name property on it. Throw a name property of, like, route. I found an example on the Svelte docs for named routes.
JASON: Okay. Let's go into layout. Does it need to have, like, any name or ‑‑
JAMES: I imagine it's arbitrary. So, I was just gonna call it, like, route, I guess. Chat saying I've always just ignored that.
JASON: I think we might need to because it doesn't.
JAMES: Oh, lame. I don't know.
JASON: Not sure. We can just ignore it. It's not that big of a deal. It's not causing anything to break. Okay. So, all right, we ‑‑ I mean, we've done the thing, right? This is pretty great that we were able to, you know, this quickly ‑‑ oh, wait, now I've broken something. Because we're not dropping it into that slot. Does it need to be ‑‑ default is a reserved word. Okay. All right. Back to where ‑‑
JAMES: Fine. I'm done with you.
JASON: All right. I'm logged in. I have my ability to create tasks. Right? And we can toggle whether or not those are done. And so, yeah, I mean, this is ‑‑ this is pretty powerful stuff. Like, you know, even with us messing up and opening this in the wrong tenant, right? We were still able to get the whole thing going. We're less than an hour into building this thing and we've got a fully functional authed app. And so, you know, a future thing that we could do with this that would actually be kind of fun, you're at PlanetScale now. We could hook this up and send this in to a database so that this could be pulled from anywhere, right?
JAMES: Yeah. That's actually one of my plans, yeah, to do some content around that.
JASON: Oh, nice. Yeah, because I think this would be ‑‑ it's very powerful. It's very approachable. I feel like this was, you know, there are a couple of things that are a little mysterious, like this slot name thing is a little mysterious, but we were able to, even with some hackie copy‑pasting, get this thing all the way up and running, get our login/logout going, get our list from the, you know, from our well, from our local store. If we wanted to, we could go in here to our store and do something where whenever the task changed, we could go and drop them into local storage or something. Not gonna do that because there are enough questions around how that would actually work that it probably isn't gonna happen in the 20 minutes that we have left. So, maybe what we want to do is just celebrate that we were able to get this done ahead of schedule. (Laughter)
JAMES: Getting anything to work live I feel like is worth a celebration.
JASON: So, is there anything else that you want to show off in how all of this worked?
JAMES: You could do ‑‑ you could do, like, a text message notification or, like, a multi‑factor authentication, if you wanted to. That's a configuration thing in the dashboard.
JASON: Let's mess with that. That sounds fun. How does one do such a thing?
JAMES: It's one of the buttons on the left. Hover on those so I can see what those items are. Try authentication ‑‑ I forget. Maybe security. It's one of those. Password list. Try security. Multi‑factor auth.
JAMES: And then ‑‑ so, there's a bunch of different factors that you can use. If people have used Google Authenticator before, Guardian is Auth0's version of that. They've got a phone message. You can configure this with Twilio longer term. You should be able to activate for free with Auth0 with a limit of messages. It should work. We can have it send SMS message. You can customize the template. Scroll to the top. Is there an enable‑type thing.
JASON: This button here.
JAMES: It was kind of hidden. At least for me it was. Save there. All right. What are we missing?
JASON: I think we got it. So, let's log out.
JAMES: Oh, it just does it by itself. Okay.
JASON: Log out. Oh, wait, I think our log out button doesn't work. Auth0 client is not defined. What have I done? Okay. Let's dive into here. We have log in. And for that ‑‑
JAMES: You probably have log out there. I would ‑‑ I would probably just copy over that nav bar, because the nav bar has log in and log out, too. I might copy over the nav bar from there and then not duplicate the log in‑log out.
JASON: Gotcha. So, we're not doing a ton with this layout at the end of the day. We would probably need to dig in a little bit more to figure out the right way to do that, but this will be just fine for us here. So, we can drop this in. And then what we will ‑‑
JAMES: It looked like it had some red curser to the bottom of the nav bar. Or maybe ‑‑
JASON: I got to get this one.
JASON: So, here's my log out. Put this up with my log in. And then what else is over here? Log in isn't used anymore so we don't need those. Don't need these. Oh, boy, this is not much of a layout at all, is it? Let's drop this all in here. There we go. Log out. Now we've logged out. So, if I log in, it wants to take me here. Continue with Google. All right. So, what I don't know, though, is how do we ‑‑ how do we turn on the multi‑factor auth?
JAMES: So I think if you go back to the dashboard, and then go ‑‑ so, press the little back arrow that says "back to multi‑factor auth." Oh, I think we lost it. It says enabled. Scroll down again. Scroll down all the way in there. Okay. So, after you ‑‑ I think this is a little bit confusing. After you say, hey, we can use this, then you need to tell it when. Never do to FA or it's got an adaptive FA, we will prompt you for MFA stuff if there is suspicious activity. If you log in in Florida and log in three minutes later in California, that's impossible travel or whatever. That would be something where adaptive MFA would prompt you. In this case, if we do "always" and save, it should prompt.
JASON: All right. Let's do it. So, now we're out here. Not this one. We want this one. Nope. Localhost: 8888. That's open in the wrong browser. Get it over here. All right. Here we go. I'm logging in. I'm gonna use my Google. So, it should force me to do multi‑factor auth. Okay. Let me do this off screen.
JAMES: Oh, I was gonna send you a text message. (Laughter)
JASON: Okay. So, it is sending me a code. And I got it! All right. So, let me get that code in there.
JAMES: And you mentioned ‑‑
JASON: Continue. And there it is. That's really nice.
JAMES: Sweet. You mentioned earlier the idea of, like, authentication being daunting. Like I think the basic parts of it, like, once you've done it a couple times, like storing passwords securely is, like, eh, the basics are relatively straightforward, but then you get into, like, adding multi‑factor authentication, supporting different types of factors for that, sending those, like, welcome emails or email confirmation emails and things like that. Like those features just start adding up really, really quickly. It gets infinitely more difficult to build, like, the entire suite of things that you might want or need in your authentication workflows.
JASON: Yeah, yeah, absolutely. I mean, it's just nice to, like, never have to think about that. You know what I mean? Like I feel like as a dev, what I'm interested in is building the thing that I want it to build. Like I have an app that I want to build and it does ‑‑ whatever it is, it does. And the last thing I want to do is to have to roll my own solution for all of the foundational pieces that make that app possible. Like I just want to plug together these services. That's one of the things I think is so excited about this Jamstack approach, right? What we're able to do here ‑‑ why don't we ‑‑ while we're at it, go ahead and deploy this while we talk.
JAMES: Yeah, that was one thing I was gonna ask, to see if it would get ‑‑ we don't have to update environment variables or anything, because those are already set for us. Which is nice.
JASON: Okay. So, let's push. Off it goes. Here are our deploys. And fingers crossed. Nothing up our sleeve. This just does what we want it to. We'll have to see how that goes.
JAMES: We'll see one way or another.
JASON: Yeah, it should work. Fingers crossed. But I think, you know, the thing that's so exciting here is that, like, we get to build the thing we want to build. We get to kind of come up with a set of features that we want to build, and then we don't have to go and reinvent wheels to get all of these other pieces in there. We are going to have to add these to our app.
JASON: Okay. So, let's go back in.
JAMES: Yeah, thank you to Typescript tee time. What a name. I like that.
JASON: Settings. Let's go back to these. Probably don't want that, right? And that should be it, right? That should do the thing. So, let's save it. And here we are with the thing. Everybody go give this a shot, if you want. And now we can log in. Look at it go! And I have a code.
JAMES: I'm gonna test it on mine, too.
JASON: Cool. I mean, look at that. We're in production with multi‑factor auth and user accounts and a whole bunch of stuff and it took us all of an hour and 15 minutes. That is really, really, really powerful stuff. Svelte holy buckets, did that just work?
JASON: Holy buckets, indeed.
JAMES: Sweet. I just put it in, too.
JASON: I'm always blown away by that stuff. It's so nice to see how much power we actually have as developers to just go and build things. If anyone wants to go and peek at this, the code is already online. You can go and look at the GitHub repo there. James, this was ‑‑ this was less painful than I would have imagined for authentication, you know? So, here's what we should do. Why don't we start doing any additional resources, anything like that, we can transition seamlessly right into your next stream. Where should people go if they want to do more with this stack? Are there additional resources you would recommend?
JAMES: Auth0 YouTube channel has some different tutorials. Depending on what you're using. So, there's a couple of good ones with React and Angular and Next. And I think just the quick starts, outside of that, are pretty helpful. So, regardless of ‑‑ or covering a lot of different frameworks and languages and stuff, the quick starts are pretty nice for just getting set up with those basics.
JASON: Cool. Sorry. It started making noise, and I got ‑‑
JAMES: You got distracted.
JASON: ‑‑ very panicky. After the YouTube, what was the other thing you wanted me to pull up?
JAMES: Just the Auth0 quick starts. So, they've got, like, the different tutorials for the different languages and frameworks.
JASON: Gotcha. Okay.
JAMES: Yeah, the auto play gets me every time, too.
JASON: Got him. Okay. So, here's some quick starts. You can go in and look at these. So, this is nice, too, because if you just start typing React, look at that. Look at it go. And React Native. Oh, that's really nice. Lots of good stuff in here. This is great stuff. And then people can go and find you on Twitter. Let's see. The Auth0 stuff, we looked at that. Here is SvelteKit one more time, if you want to go dig into that. And let me do another shout‑out. We've had Jordan from White Coat Captioning with us all day doing the live captioning, making the show a little more accessible. That's made possible through the support of our sponsors, Netlify, Fauna and Auth0, all kicking in to make the show a little more accessible to everybody. Which I really appreciate. Make sure while you're checking this out go peek at our schedule. We've got so many great things coming up. Later this week, we're going to talk to Michael Chan, @Chantastic on the tweeters. We're going to be doing fun CSS stuff. CSS gets such a bad rap. I have so much fun doing anything with CSS. Later on, we're gonna talk about PlanetScale and your new co‑worker here, Taylor Barnett.
JASON: She's coming on on Friday. We're going to talk to Alexandra Spalato. We're going to do solid.js. A new framework ‑‑ I guess it's not even new, from Ryan Carniato. Really, really fast. We're going to do distributed databases for MongoDB. Keep your eyes peeled there. You can add on Google calendar to get those updates. Make sure you follow on twitch. Subscribe on YouTube and the ring the Bell and the subscriptions and all those things, because it makes me feel validated.
JAMES: Makes me feel good.
JASON: Yeah, I need validation, y'all. So, James, any parting words for everybody?
JAMES: Thanks for having me. Appreciate it. This was fun. I'm planning on doing more. Now that I'm, like, reminded of how much I enjoy Svelte and SvelteKit, I'm planning on doing more content.
JAMES: On my YouTube channel. And then for PlanetScale, too. So, I'm excited to tie that into some database stuff.
JASON: You're about to do that right now, right? You're gonna head over to the PlanetScale Twitch?
JAMES: Yes. I'm gonna go ahead ‑‑ I'm gonna start this. I'm gonna have it with, like, a placeholder screen. Let me just verify. It says it's live. Let me verify that PlanetScale is live.
JASON: I'm looking. I'm looking for PlanetScale.
JAMES: Please be live. Yeah, it's live.
JASON: Okay. Let's see if we can raid PlanetScale. Is that gonna work? Maybe.
JAMES: Is it slash command or exclamation?
JASON: I don't know how any of this stuff works.
JAMES: I can't remember. I think it's slash. Is it?
JASON: I don't even ‑‑ you're probably right. All right, everybody, we're gonna call this one done. So, let me switch into the outro screen. We'll go and figure out how to raid PlanetScale. Stay tuned. We're gonna go hang out with James for some PlanetScale stuff. Thank you so much, James. We will talk to y'all next time.