Build & Deploy An AI-Powered Chat App | Vue, Node, TypeScript, Open AI, Stream & Neon Database
Chapters32
The video outlines building a full-stack AI-powered chat app named Chat AI, shows a live demo of signing in, chatting with context, and saving chats, and lists the tech stack (VJs/Pina on frontend, Express/Node on backend, OpenAI API, Stream Chat, Neon PostgreSQL, Drizzle ORM) plus deployment targets (Render for backend and Vercel for frontend).
Hands-on guide to building and deploying an AI-powered chat app with Vue 3, Pinia, OpenAI, Stream, Neon, and a split full-stack setup.
Summary
Traversy Media’s deep dive walks you through architecting a full-stack AI chat app called Chat AI. Brad starts with a demo: a logged-in user can chat with an AI that remembers context like “who was the 10th president of the US” and even preserves chats by email. The frontend uses Vue 3 with Vite, Pinia for state, and TypeScript, while the backend stacks Node/Express, TypeScript, OpenAI GPT-4, and Stream’s chat APIs. For persistence, Brad chooses Neon’s serverless Postgres and the Drizzle ORM to create and migrate schemas for users and chats. The project is organized into two repos (Chat AI API and Chat AI UI), deployed to Render (backend) and Vercel (frontend). Brad also covers docs navigation (Stream, Neon, OpenAI), environment setup, and a workflow that includes TSX, ESLint-like config, and two-factor deployment steps. He demonstrates registering users, creating channels in Stream, saving chat logs to Neon, and then querying chat history via a dedicated endpoint. Finally, the talk walks through deploying both halves and testing end-to-end, with notes on adding chat context and formatting AI responses for nicer display. This is a practical blueprint for developers looking to stitch together modern frontend, robust back-end services, and AI capabilities in a modular, scalable way.
Key Takeaways
- Split architecture: a stand-alone Express API (Chat AI API) and a Vue-based UI (Chat AI UI) to keep front-end and back-end concerns separate.
- Pinia for front-end state: use Pinia stores (user and chat) with persisted state to keep users logged in across reloads.
- OpenAI GPT-4 integration: use the chat/completions API with a context-enabled conversation to yield context-aware AI responses.
- Stream Chat for real-time messaging: install GetStream.io, create users and channels, and wire them into the app for real-time chat capability and logging in Stream’s dashboard as proof of usage and logs—while Neon stores your own copy of users and chats for extra control and analytics.,
Who Is This For?
Essential viewing for full-stack developers who want a practical blueprint for building and deploying an AI-powered chat app. Great for Vue/Node teams exploring Pinia, Neon Postgres, Drizzle ORM, and OpenAI integration, plus deployment with Render and Vercel.
Notable Quotes
"AI is thinking and get back the 10th president of the US was John Tyler now it's going to keep the context."
—Demonstrates the AI maintaining chat context across queries.
"we're going to set up our own database our postgres database with neon so neon offers serverless postgres databases that you can literally set up in like 10 seconds"
—Introduces Neon as the chosen persistence layer for users and chats.
"the front end will go to vercel"
—Describes deployment targets for frontend and backend.
"we're using the open AI API the completions API using gp4"
—States the core AI service used for generating responses.
"we have a channel created and then we can send a message through the channel"
—Shows how Stream channels are used to propagate messages.
Questions This Video Answers
- How do I set up a two-repo project with a Vue UI and an Express API backend for an AI chat app?
- What are best practices for persisting chat history with Neon Postgres and Drizzle ORM in a Node/TS project?
- How can I add context to OpenAI GPT-4 prompts to support multi-turn conversations in a chat app?
- What does deploying a Vue front-end to Vercel and a Node API to Render look like in a real project?
- Which Stream Chat features are essential for building a real-time chat app with channels and logs?
Full Transcript
hey what's going on guys so I got a really cool project for you today we're going to be building a full stack AI powered chat app called chat Ai and I'm just going to give you a quick demo before I explain anything so we just log in and and you just have to put your name and email and then we can go ahead and say something we'll say like um we'll say who we'll say who was the 10th president of the US okay so it says AI is thinking and get back the 10th president of the US was John Tyler now it's going to keep the context so if I just say simply who was the 12th it's going to know what I'm talking about so the 12th President uh was Zachary Taylor all right and if I were to log out or leave the chat and then come back with the same email my chat will be saved all right now to achieve this we're going to be using VJs and pinea for State Management on the front end and no.
JS and Express on the back end and we're using typescript on both the front end and backend now there's a bunch of technologies that we need to incorporate to achieve this for the whole artificial intelligence aspect we're using the open AI API uh the completions API using gp4 and then for the whole chat aspect we're using stream chat at getstream.io so stream offers sdks for powerful applications that Implement real-time chat as well as video and audio and and this is just one of the many ways to use stream chat so like I said it's going to handle the whole messaging aspect the users the channels now even though stream does store your chat logs and stuff we're going to set up our own database our postgres database with neon so neon offers serverless postgres databases that you can literally set up in like 10 seconds and there's features like branching it's extremely scalable and we're going to set it up so that our our project saves the users and the chats in the neon database and then we'll be using the drizzle orm to interact with the database uh as well as create schemas run migrations and so on and then at the very end we're going to deploy the back end is going to go to render so render doc um and then the front end The View application will go to versel all right so this is just an all-in-one Dev to deployment project I have the repositories for both the front end UI and the back backend API in the description so I would suggest you follow along with me I think that's the best way to learn so let's jump into it all right so I just want to quickly go over some of the websites where you can find the documentation for different parts of this project so first off we have stream chat which we'll be using for all the chat aspects and you can find the docs at getstream.io if you go to Developers and we're using the chat messaging there's also video and audio capabilities if you want to check that out but if we go to chat messaging there's all these platforms that we can choose from and we're using it on the back end so you want to choose the the node.js option and then from here you have all different topics like users tokens permissions um creating channels and all that good stuff so that's for stream chat and then for neon which is our Cloud postgres database you can go to neon.pdf here and then finally we have openai which is at platform.
open.com and this is what we're using for the whole AI aspect of it and we are going to have to generate API keys for open AI for neon and for stream so you might want to just just keep these websites open so let's go ahead and just open up a terminal and just navigate to wherever you want to create this project and we're going to have two separate folders for the back end and front end the back end will be chat AI API and the front end will be chat AI UI that'll be the vue.js back end will be the node and expr Express so I'm going to put both in a parent folder so let's create that so I'm going to say make directory and chat Ai and then CD into that chat AI folder and make another directory called chat AI uh- API and that will be our back end and I want to open that up in in vs code so I'm going to say code and then chat AI API and of course if you want to use a a different text editor that's absolutely fine okay I'm going to be using my integrated terminal so I'll go ahead and open that up and we just want to run npm in nit of course you need to have no JS installed and let's go through this so package name version that's good description let's say this is going to be a backend for uh we say for an AI chat application and then s uh entry point I'm going to call server say server.js and then author you can put your own name if you want and MIT for the license so type I'm going to be using ES module so we want to put module instead of commonjs I mean if you want to use commonjs you can but um we'll be using import all right so now that we've done that let's install our dependencies and I just want to quickly go over what our backend dependencies are going to be so we have Express of course which is our backend web framework cores which which allows access to resources from a different origin that's because our front end and back end will be on different domains EnV allows us to use environment variables from a EnV file stream chat is the official JavaScript client to work with stream chat in nodejs or in JavaScript and then open AI is the client to work with the open AI API typescript we're going to be using on both the back end and front end a little bit more to the setup in the the back end but it's not too bad we're going to be using something called TSX to execute our typescript because even though with node.js version I think 23 um typescript is supported but all it really does is is strip your types it doesn't actually compile it doesn't execute it so that's where TSX comes in if you want to use TS node or something else you can and then drizzle is the OM to interact with our postgis database and then drizzle kit is a CLI for drizzle and we'll install the drizzle stuff a little later but let's install some of these dependencies now so let's say npm install Express we want what else cores we want EnV um stream chat so stream Das chat and also open AI I think that's I think that's all I want right now as far as regular dependencies now for for Dev dependencies let's say npm install D- uppercase D and we want typescript and I'm also going to install TSX to execute the typescript and then for types we'll do types SL node let's say at types SL Express and also types slash cores now as far as uh as our typescript config goes we're going to create our TS conf fig with npx and let's say TSC D- init and I'm going to open that up and there's I have a configuration that I'm going to use if you want to use the same one you can just get it from the link in the description the the GitHub repo but I'm going to paste this in so it's pretty simple we're going to I want to use es modules and all that all the latest features so using node next for module and module resolution and Es next for the Target our output directory when we compile our typescript is going to be slash and then our root directory where we write our code is going to be SL Source okay we're using strict mode or strict type checking U and then we're allowing importing commonjs modules we're allowing importing of Json files as modules and we're skipping the Declaration files in the node modules folder to speed up compilation so pretty simple setup we'll go ahead and save that file and and then we want to create our scripts in package.json so we want a Dev script and of course with our Dev script we want to compile our typescript so we're going to use TSC so the typescript compiler and then we're going to add-- no emit because we don't actually want to produce JavaScript files when we run this we're just running our Dev server and we just want to compile our typescript and we also need to run TSX as well and we're going to run that in watch mode okay so no need for like node Monon or anything like that and then that's going to be source and then server.
TS will be the entry point so that's what we want to run okay and then to build our project out to just compile we want to run just TSC and then the start script so to run in production is just going to be node and then it'll be in a disc folder and it'll be called server.js so that's all we need for uh for our npm scripts all right so now let's create a folder in the rout called Source that's where we will write all of our code and let's create our entry point which is going to be server.
TS I mean if you don't want to use typescript that's fine we're not doing too much as far as typescript goes so even if you're not familiar with it you should be all right Honestly though it's really becoming the standard so I mean you're going to be creating TS files and TSX files all the time so I mean I would suggest learning the basics of typescript if you don't know it so let's just create a basic Express server so we want to import Express from Express and we want to import uh let's see we want to import cores as well and we also want to import EnV and then we want to call env.
config and then we'll initialize our Express app so set that to express okay we need have some middleware to add so cores requires us to add an app.use and we're also going to do app.use express. Json because we want to be able to um when we send a request we want to be able to send Json in the body we also want to be able to send form data so let's also do app.use and say Express and then URL encoded and then just pass in an object with extended and set that to false all right and then we want to create our Port variable and I'm going to set the port in the EnV so I'll say process.
env. port or then use 5000 and then let's just uh take our app and let's listen on that Port whoops listen on Port and then when that happens we'll just run a console.log and put in some btics here and we'll say the server server running on and then output that Port variable all right so let's um let's create ourv so that's going to go in the rout not in the source folder and from here we'll say port and for now I'm just going to set it to 8,000 because I want to make sure that it's actually reading this value so down at the bottom here at the terminal or wherever your terminal is let's run npm run Dev okay so server running on 8,000 and it'll compile any typescript we have obviously we don't have any right now and before we start to add our route I just want to make my my first commit so I'm going to open up a new terminal here and let's run and get a knit and then we'll create our do get ignore uh CU you definitely don't want to push thatv so let's add not node modules and Dot EnV all right so I'll say get add all get commit oh what's this don't care get commit and we'll just say initial Express setup set up our initial Express and TS setup all right so now what we want to do is have make our first route and what this is going to do is it's going to reach out to to stream chat and it's going to register a user with stream okay because you can actually log into to your stream dashboard and you can see the users that were registered for um what is this doing here for your for your application and it when I say register it's not traditional authentication where you're going to have a password and stuff basically you come to the the app and you put in your name and email and then from there you get sent to the you know the the form to interact with the AI so let's start by just creating a route now since we're using typescript we're also going to bring in from Express we want to bring in uh request and response uppercase R and let's create our first route we'll go down here let's say I'll put a comment let's say register user with stream chat and it's going to be a post request so app post and for the endpoint we'll call this excuse me we'll say SL register D user and then we're going to have an async function here okay and then as far as what this returns will be a promise and we're just going to add any to this and then it's going to take in the request and response and we want to set those to those types so request and then res which will be response and then just to test it I'll do a res.
send and we'll just say test okay so now we have our first endpoint now as far as how you test your endpoints it's it's really up to you I I like to use Postman and I have the postman extension for vs code so if I click on this icon right here I can make a a new HTTP request and it just opens up in a new tab which is nice so I'm going to make a post request to http and we want Local Host and I have it running on 8,000 and we want to do register Das user and you'll see I get a 200 response and I get test so we know that that that route is working we also want to send an a name and email so why don't we do a little bit of validation here we'll say if or first of all let's get the name and email so that'll be in the request body so let's say cons and then we'll destructure the name and email from requestbody and then we'll say if not name or not email then we want to send back an error so so we'll return res Dot and let's do a status of 400 which is a user error and then we'll attach the Json uh let's just put an error here and we'll say name name and email are required and then after the if I'll just do a res.
status say 200 and Json message success all right so let's try that out so if I just send as is I get the error but if I send a name and email in the body I can either do Json data or I can use the form URL encoded so I'm just going to add name and email and then send and I get success all right so now we want to start to work with stream we installed that you should have the stream client so if you just look in your dependencies you should have stream chat that's what we're going to use now in order to create an instance we have to we we need our API key so we're going to have to go to the getstream.io and just you can log in with with either GitHub or Google so I'm already logged in I'm going to go to my dashboard and you don't have to pay anything or enter any credit card info for this we want to create a new app and this has to be unique so I'm just going to say chat Dash uh we'll say chat Ai and I'll just do das Brad you could put your own name whatever it just it has to be unique and then just choose the locations for the the chat and video storage and feed storage that's closest to you and click create app and then you'll have your keys right here we have a key and a secret we need both of these so I'm going to copy the key I'm going to go into myv and we're going to add stream API key and set that to the key and then we also want the stream API secret which we can get from right here just going to copy that okay so I'll paste that in now that we have that we should be able to create an instance so let's bring in the library so import or the client and that's called stream chat and then we're going to create it or initialize it right above our row let's initialize initialize the stream stream chat or stream client so we'll say const we'll call this chat client and I'm going to set that to the the stream chat stream chat Dot and then it's get instance and then that's going to take in your API key and your API secret so let's say process Dov Dot and then stream API key and I'm going to put a bang on the end of this which is a nonnull assertion so I'm basically telling typescript that this is it's not going to be null or undefined it's definitely there and then we'll do the same with the secret that gets passed in as well okay so now we should have our chat client initialize now we can use it in our route and the first thing I want to do is is create an ID because when you create a user it needs to have a unique ID and it's up to you on what you want that ID to be I mean you could install a package like uuid but what I want to do is take the email you don't have to type this out but let's say that the email is Brad gmail.com then I want the ID to be brador gmailcom so that way we have a unique ID but it's also readable it's understandable all right so let's um let's do that so I actually want to after we do the if here let's wrap this in a TR catch and I'll move this this success I'm going to move that into the try and then let's copy it and then in the catch if something goes wrong then I'm going to send a 500 error so let's change the status to 500 and for the message we'll just say or it's actually going to be error so error we'll say internal server error all right now in the try let's generate the ID so we want to say user ID and we have access to the email that they enter so we're going to use replace and replace takes in it'll take in what we want to replace and what we want to replace it with so and we pass in a regular expression I know a lot of you guys and including myself hate regular Expressions but this is pretty simple so in Brackets we're going to use the uh the carrot so basically we're saying if not if it doesn't match whatever I type here which is going to be a lowercase A to Z so a low lowercase letter or an uppercase A to Z or 0 to9 or an underscore or a dash if it's anything other than that I want to replace it with an underscore and I want this I want it to be Global so I'm going to put SLG so the second argument you pass in is what you want to replace it with which in our case is going to be an underscore okay so that'll generate the user ID in fact we can go ahead and do a console log of user ID just to check and then if I make a request again with this Brad at Gmail and I send if we look down in the console brador gmailcom and again if you want to do something different for IDs you can so yeah let's get rid of the console log and now I want to check to see if the user exists in stream chat so let's say check if user exists and we can do that let's put this in user response and this is a synchronous so we want to do await and then chat client and then there's a method called query users so we want to use that and then what we can do is pass in an object where we want to match the ID and we set that to an object with this money sign EQ so we're saying if it equals the user ID and we can do a console log of that as well and then just go ahead and send and if we look down here you see it gives us an object with a duration and the user's array which is empty because that the user doesn't exist that um in my case it would be the Brad gmailcom doesn't exist so what we can do after that after we check if the user exists or after we set that variable we'll say if not user response.
users. length so we're saying if that array is empty then we want to add new user stream so we can do that with the uh there's a few different methods we can use I'm going to use upsert user which will create or update a user so let's say chat client. upsert we want to do it's just a single user so upsert user and then we're going to pass in an object I'm going to assign the ID to the user ID which will be that formatted email the name set that to name and the email and then I'm also going to add the role of user because there's there's different roles there's an admin user as well in fact if we look at the the docs here if I search for roll permissions let's see yeah so right here buil-in roles so user is a default user role you have guest um you have admin which is a role for users that can perform administrative tasks with elevated permissions so we just want a a regular user now I should also mention that this is where you you can also generate a token so let's see um we could call right here create token however we're we're using this on the server side with an API key so we don't need to do this but if you were using this from you know react or view or some kind of front end then you would want to create a token and you'd want to save that and then send that with your um you know the rest of your requests so but we don't have to do that so yeah I just want to return now basically just return the user ID the name and the email so let's go right under that if actually we already have this we might as well just use that um yeah we'll get rid of the message and let's send the user ID the name and email and I think that should do it so we can try it out now so I'm going to come back here I'm going to register the user Brad gmail.com let's click Send and I get back a 200 I get back my that's my user id formatted from my email my name and the actual email now you should be able to actually log into your dashboard so if I go to my chat AI app here and under chat messaging if I go to Explorer you can see I have my chat AI Brad app has an app ID app name if I click users I got Brad 90 not sure where that came from but right here is the the user that I just created and it has all these fields it has the ID the name language role created at updated that if the user banned if they're online if they're invisible so lots of information uh and you can delete users too in fact I'll delete that Brad 90 user oh it's an original dashboard user okay so I can't delete that all right so we're able to to register users now for the chat and later on we're also going to implement our neon postgres database so that it saves users there as well and it also saves all the chats all the logs but before we do that let's create our chat route chat route so that we can send a question or or whatever it is we want to send to the AI and use the open AI API to respond to that so let's first of all bring in the open AI client so up at the top here we'll say import and it's going to be open AI from open Ai and then we need to initialize open AI here as well just like we did with stream so right here I'll say initialize open AI now we are going to need an API key so why don't we do that real quick I'm going to jump over to platform.
openai and log in so from here if we click on settings go to API Keys you should see them here um I'll just create a new one let's say chat and for project I'll just use um project one okay so I'm going to copy that and then I'm going to go ahead and add that to myv so here let's say opencore AI uh actually no let's do open AI underscore and then API uncore key and then set that okay so now what we can do is initialize here let's say const open a excuse me open AI set that to new uppercase o Open Ai and then pass in our API key which is going to be process.env do open aore API key okay so that'll initialize that now let's create our our chat route so I'm going to go under the register user and let's say um what should I say here let's say send to Ai and this is going to be a post request as well so app post and the route is going to be just slash chat and then let's say async okay I'm going to return say promise and any and then we're going to pass in the request and res response all right so the first thing I want to do is get from the body there should be a message and there should be the user ID because when you register a user you get the ID and then you're going to send that along to the chat route so let's say const and let's get the message and the user ID from the request.
body and then we want to just make sure that that exists so we'll say if not message or not user ID then we're going to want to return let's say status 400 and Json we'll say message and user are required all right then we're going to go under that if statement and let's open up a TR catch and in the catch we're going to I'll just copy this response here except we're going to change this to a 500 and then for the [Music] error for the error we'll just say internal server error and in the try first thing we're going to do is let's say verify user exists so we'll say const user response we want to set that to a wait on the chat client and then we're going to use Query query users pass in an object we want the ID to match the user ID okay after we do that let's check that response we'll say if not user response remember it has an array called users so we're going to check that we're going to check the length and basically if it's an empty array then we know the user isn't hasn't been found it doesn't exist so let's return res.
status and four we'll do 404 because it's a not the user's not found and then we'll we'll do Json and let's pass in an error and for the error we'll say user not found and we'll say please register first all right now before we do anything else let's just let's just check if that works so we'll just do a simple res. send and just say success okay so when we make our request now to slash chat it should reach out to stream and uh in the body I don't have uh I don't have anything so I should get this message and user are required so let's add in the message I'm going to say what is the capital of Massachusetts and then for the user ID for the user ID I'm going to put a user that doesn't exist I'll just do one two three and if I send that I get user not found please register first now we know that the user ID for me brador gmailcom we know that that exists so let's try that out and we get success so so far so good now what we want to do is start to work with open Ai and we're going to use the chat completions API which will work like chat GPT you send it a prompt and it sends you a response so let's go right here where I have the res.
send and delete that and let's send the message to open Ai and we're going to be using the gp4 model so we'll say con response and set that to await open AI and it's going to be chat dot completions Dot and then create and then we want to pass in an object that has the model that we want to use which in this case is going to be GPT you have all these different options we're going to do gp-4 so that's the model we want and then we send messages which is going to be an array and we're going to pass in an object here with a rle of the user and then the content is going to be the message all right so whatever we add in the message which in my request is just what's the capital of Massachusetts now I want to show you what that gives us so why don't we just do a console log of the response and then as far as what we return I'll just let's just do uh yeah we'll just say res.
send success okay I just want to see what what this gives us so let's come back over here and I'm going to send the same response with the message and the correct user ID we get success but let's take a look in the in the console here and we get this object has an ID blah blah blah what we care about is this right here this a choices array and there's an one object in there with a message and we can't see it here we just see object um yeah I don't think we can see that so why don't we log that so we got console log response and then it's going to be dot choices which is an array we want the first and only item in that array and we want the message okay let's send it again and there we go so we get an object with the role is assistant okay so it's the the AI That's responding has a role of assistant and then content is what we're looking for the capital of Massachusetts is Boston all right so it's as easy as that to to create a prompt and get back a response so now obviously we want to return that response from the endpoint so let's come back in here we know how to access it now right with this it's actually message.
content that will give us the exact you you know what we're looking for so let's get rid of the console log here around this and let's put this into a variable we'll say const AI message and um let's type that it's going to be a string and set it to that so response choices message content now I am going to use um optional chaining here for for uh message so just add a question mark there and then we also want to use a nullish coalescing operator because if that happens to be null or whatever then we're just going to make it no response from AI that'll get rid of any typescript errors now before we actually send this AI message back from this endpoint we need to create a channel which is used for managing conversations in fact if we go to the docs here and we search for Channel and then creating channels so it shows us how to do that we store a reference in a variable using our client and then.
channel pass in the type which is going to be messaging okay there's different types if we come down here and look at type you have um live stream messaging team gaming Commerce messaging is is for like you know one-on-one conversations or group chats um that's uh typical type for things like that and we're having a one-on-one chat with it's just not with a user it's with the AI so that's what we're going to use and then once we store the reference we can then call channel. create and then we can actually do channel. send message as well which will send the message through through the channel it'll get stored and so on so let's um let's do that let's go right below the AI message and let's say actually I'm going to just put a comment here let's say create channel or it's actually create or get channel and we're going to create the reference with our chat client.
channel the type is going to be messaging and we can also pass in a unique ID which I'm going to use back ticks and then just say chat Dash and then the um the user ID so that'll be a unique identifier and then we want to pass in an object with the name of the channel which I'm going to call we'll call it AI chat and then we also need to add this created uncore byor ID which if you were chatting with another user then it would be that user but since we're using an AI we're going to call it AI bot all right so that will will create the reference now we need to call channel.
create like I just showed you in the docs and then after that we can do uh sorry this needs a wait and then after that we can do await channel. send message and pass in an object with the text which will be the AI message so AI message and then the user ID and make sure you do user uncore ID that's what the key is it's not camel case it's underscore and then that's going to be the AI bot that sends this message okay now as far as what we want to respond with let's do res.
J actually we'll do status 200. Json and then pass in um an object oops passing an object with a reply and that reply will be the AI message oops not Al message AI okay so yeah that should do it and then I just want to do a console log here as well if there is an error let's put um error generating AI response and then also the error all right cool so let's try that out I'm going to come over here and I have I have my message I have my user id let's go ahead and send and we get an object with the reply the capital of Massachusetts is Boston and what's cool is now if we go back to the stream dashboard and if we go to you know chat messaging Explorer we have the AI bot user here and you can see under channels we have messaging so it's that's the type and then we have the unique identifier which is chat D Brad Gmail com because I set that right here right that's the unique identifier and then we should be able to see any messages that are in through that channel so we have one message here and it shows the text which is the capital of Massachusetts is Boston so whatever the AI sent us back so pretty cool now what I'd like to do is Implement our own database I mean we do have the the you know you can see the chats and using stuff through stream but a lot of times you want to do more with it so you'll want to store the chat logs in your own database so I want to expand this to to do that and also store our users so you want to create uh a postgres database through neon so I'm going to go ahead and log in here all right and then we're going to go to well yeah I guess we'll create a new project so once you log in and this interface is is so easy to use and it's so easy to set up a database it's basically just a couple clicks so I do want to create a new project I'll call uh tutorial and you can choose your postr G version I'm going to stick with 17 your database name I'm going to call this chat chat Aid DB and I'll just choose AWS and then create and you can do a lot from this interface I mean you can run straight SQL queries there's branching so just like you have branching with GitHub with your code you have branching with your databases so if you want to whatever add a new feature and you don't want to affect the main branch you can just create a new Branch work with that once that's all set and you know that's what you want to use then you can merge the branches so really cool and what we want to do now is just click connect and that will give us our connection string so right here we want to copy this and actually let's click show password too and then copy and we want to store that that uh reference to the the database the database string in ourv so let's go in there and let's call this database uncore URL and go ahead and paste that in all right right so now that we have that we need a way to interact with our database and that's where drizzle comes in drizzle is an OM it's typescript base it's really easy to use um but one thing we do have to do since we're using neon is use the neon database serverless adapter so we do have to install that as well so let's come down to the terminal here and let's run npm install and we want drizzle Das omm and then we also want to install at neon database SL serverless okay so it just allows us to to use um drizzle and to use this with with uh neon's infrastructure and then we also want to install drizzle kit as a a Dev dependency so let's say npm install Das uppercase D and then drizzle dkit and this is a CLI and we can run migrations from it and stuff okay so now that those are installed a couple things we have to do a few files we need to create so one is going to be our database config file which I'm going to put in the source folder I'll create a new folder called config and then in that config we'll have a database.
TS file and this is where we configure That Neon database adapter so let's go ahead and import a couple things here first one is going to be Neon and that's going to be from this right here neon database SLS serverless then we want drizzle so import drizzle and let's see we're going to bring that in from drizzle omm and then it's going to be slash neon HTTP and then we want to bring in from dotv package we want to bring in the config function because we're going to be using environment variables so let's go ahead and load environment variables and we do that by calling config and then since I have this in you know in the source folder than in the config folder I'm just going to specify the path to the EnV file you can do that by passing in an object like this just say the path and it's justv because it's in the root okay cuz that's going to start in the root all right then we just want to check for the database URL so if not process.
env. database uncore URL then let's throw a new error and we'll say database uncore URL is undefined okay so we got that um next thing we want to initialize the neon client so actually going to put a comment here so init the neon client and we're going to put that in a variable called SQL so we set that to Neon and that's going to get passed in the database URL so process. EnV do database URL and then we need to initialize drizzle and that's going to be exported because we're going to be using this in other files so we're going to call this uh variable of DB and then we set that to drizzle and that gets passed in the SQL variable which is the neon client so we can close that file up and now we want to create our schema and if you've used like Mongoose or SQL eyes or Prisma we create a a model or a schema of our data and then we can use drizzle kit to run the migration looking at that schema and it will create the tables for us so I'm going to put this um in let's see we'll have in the source folder I'll have a folder called DB and then in DB will have a schema.
TS file all right so let's start off by importing what we need from drizzle so we need PG table which is going to create post postres tables for us and that's going to come in from drizzle o/ PG core so in addition to that any Fields any field types that you want to use you bring in here so for instance serial which is what our primary key IDs are going to be and then text and then timestamp I believe those are the only ones we need so what we do now is export for any any table we want to create we export uh uh PG table function that takes in the name of the table and then all the fields we want to use so for instance for the chats let's say const chats and we want to set that to PG table and the name of the table will be chats and then we pass in an object with all the fields that we want so for instance the ID is Going to Be A Serial type serial field and that's going to be named ID and then I want that to be the primary key so we can tack on do primary key next thing we want is the user ID so that's going to be text and user undor ID uh and then let's see we're that's going to also be not null so we'll tack that on then we have the message so let's say message of the chat and this will be message as well then we want the reply which will be the you know the message that's sent back from um from the the AI so that'll be text as well and reply and not null all right and then the last thing I want here is created at so created at is going to be a Tim stamp and that's going to also be called Crea underscore uh at and let's add on to that I'm going to use default now which will do the current time stamp and that should also be any parenthesis there that should also be not null all right so that's our our chats now let's do the users because I want to store users as well so we'll say con users not exports so cons user set that to um PG table and the name of the table will also be users and then we want to pass in all of our Fields so first thing is going to be ID which will be text and user ID for the column name and this is going to be the primary key so we want to add that all right then we get the name so name will be text as well name for the column name and not null all right then we got email so let's change this and this to email and then we want a created at so I'm just going to copy this one because it's the same thing okay so that those are the two schemas and the two tables we want to create now drizzle is is really great when it comes to typescript we can have our type inference in inference for drizzle queries so basically when we insert a chat for instance it's going to be structured in a specific way with a specific type and we can add that here the type inference for the chat insert for the chat select for the user insert and for the user select so we want to export the so we can use them outside of this file and we're going to say type and then chat insert and we want to set that to type of and then chats and we want this infer insert okay money sign infer insert and then we want to do the same for the chat select which is going to be infer select and change this to chat select okay and then we want to do the same thing for users so what I'll do is just uh whoops what I'll do is just grab both of these and copy those down and then we're going to change this first one here to user insert and make sure we change this users and then this one here change that to users and this one is going to be users select like that okay so that takes care of the type inference for those types for insert and selects now we want to create a config file for for drizzle or for drizzle kit because it needs to know where the scheme is are it needs to know um where the migrations will go things like that so that this is going to go in the root because that's where it looks so in the root not in the source but in the root we're going to create a drizzle.
config dots all right and we want to import let's see we're going to be using EnV so we want to bring in the config from that so that's going to be from EnV and then we're going to import Define config and that's going to come from drizzle kit and then let's just run uh let's say config because we're going to be using the environment variables to get the database URL and again I'm just going to specify path and it's just in the root. EnV okay and then we want to export as default Define config and then that's going to get passed in a couple things so first is going to be schema and that's going to point to what we just created which is going to be from the root in the source folder and then in the DB and then schema schema.
TS okay so that's our schema um then we have out so this is going to be the migrations folder so just uh it's going to be slash migrations all right then we have the dialect so dialect I mean you can use drizzle with different databases MySQL Etc we're using postgres in fact you can see the options here so we're going to use postgres and then the for the DB credentials that that's going to be an object and we just need to provide the URL which is going to be our process uh env. database URL and let's just add a bang on the end that all right so that's our config so we can close that up now since that drizzle config is in the root directory we are probably going to have an issue with typescript because it's compiling the The Source folder right so we can run into an issue there so what we can do is exclude that file so under compiler options right so it ends right here so under compile options we're going to add exclude and it's going to be an array and we just want to add in that file so we want uh drizzle what is it drizzle.
config dotx yes and that just cleared up that error that was there okay so now we have our schema created so that means that we're ready to create our migration and when we create our migration we first generate it and then we we do drizzle kit generate and then drizzle kit migrate and that should actually create our tables for US based on this based on the schema so let's try that let's come down here and let's run or we need npx and drizzle dkit and then we want to do generate first okay so your your SQL migration file so it created that here and then and you'll see there's a migrations folder here now then to actually migrate we want to do npx drizzle kit migrate all right so let's see you can only connect to remote super B instances through web socket not exactly sure why it's saying that it is a warning so let's go to our neon dashboard and let's check it out so if we go to tables and we have our chats yep chats table you can see the fields here ID user ID message and we have our users table okay so that worked I'm not exactly sure can only connect to remote neon versel postgress through a web socket um I guess I'm just not going to worry about that right now because it did work it created our tables from our schema which is what should have happened so now let's integrate the database into our endpoints into the register user and into the chats because again we want to save the users we want to save the chats actually let's bring in up top what we need to First okay so we're going to import we want our DB right so DB which is going to come from our database now this is something that I want to mention when you're using typescript with node with with TSX and you have the configuration that we do when you import a file because this is the first file that we've imported the rest have just been you know package modules so you it says JS even though it's a TS file okay you can't do import TS that's not going to work it's going to give you an error so even though it says JS everything to do with typescript compilation everything is just it still works fine this is just the syntax we have to use so in addition to that we want to bring in our schemas so chats and users and that's going to come in from slash DB and then slash schema and again we're going to do schema JS even though it's a TS file and then let's see what else do we need um there's a utility called EQ to to basically compare values to compare the users and so on so that's going to be EQ from drizzle omm and then what else do we have here uh the oh the chat completion message pram type so we're going to bring that in as well so chat completion I don't see it here completion message right here so that's going to come from openai resources MJS actually we don't need the MJS I don't think yeah that should work okay so now that we we have our Imports let's figure out where we actually want to use the database so we have our register user right so that creates a user with stream but again we want to also save the users in our own database so I'm going to go down right above the the response okay after we deal with all the stream stuff and let's check for existing user in the database I know we checked for if it's in stream but we also want to check in our own database so let's say const existing user and I'm just going to close that up and we want to set that to a wait and this is where use the DB right so DB from our config file database config and then I'm going to call a few different methods on this one is Select so I want to select from the users table where so do where this is just the syntax of drizzle which I I like pretty clean so where now this is where we use that EQ utility so we want to pass in EQ and we want to see where users do user ID is equal to the user ID okay and that the user ID would be you know what we create from the email when a user is registered so it's going to check for that and well it's going to put it in this variable now let's come down under it and let's say if not existing user uh we'll say if not existing user.
length then let's just um we'll first off we'll just do a console log and I'll put some back ticks in here and we'll say user and then the user ID uh we'll say does not exist in the database and we'll say adding them because that's what we're going to do all right so under that line let's await DB and then we're going to call insert and we want to insert into users where values okay so the values we want to add pass in an object here with the user ID the name and the email all right and that should be it so let's save it now and I'm going to come back to uh to postman so let's send a request so I'm going to make a post request to http we want to do register user and in the body for form data let's add a name and an email okay so I'm going to go ahead and that all right so I get back what I'm supposed to to now we want to check the database so let's go to uh to Neon just going to reload this and there's the user so user ID which is also the primary key the name email and the created ad so now not only are we do we have the users in the chat Explorer and stream we have it in our own database which we can do whatever we want with right and I had deleted the the user before so there it is again all right so in addition to the users in the database we also want to store the chats so let's go back to server TS and let's go down to the chat endpoint and figure out where we want to use the database here so let's see we're getting the user response here right then we check the user response so let's go right under that and we'll say check check user in database so again we're going to do const actually I can just copy the the line of code I just put here okay so we'll add that here and then um actually we can take what we put after that too which is this except we're not going to create the user so we do have to change that so right under where we check the user let's paste that and uh we're going to get rid of this insert we don't want to do that and then for the actually we're not even going to do a console log we want to return an error if the user isn't there so let's say return and then res.
status and we'll do 404 and let's do Json error and we'll set the error we'll say user not found in database please register first okay so we're making it so that if the user isn't in our postres database our neon database then it's still it's not going to let it happen right it has the user has to exist in stream and it has to exist in our database so now let's go under where we get the AI message message and store that and let's say save we'll say save chat to database so to do that we can just say await db.
insert we want to insert into chats or the chats U table and then for values we're going to add the user ID we want the message the reply uh actually reply we're going to set that to AI message okay so we're just taking whatever this is right and we're just storing it as reply and that's it so now we can try that out so I'm going to come over here and let's go let's make a request to chat and we're going to change the stuff here so let's say message and let's do something different um Let's do let's do something a little more difficult like create a simple let's see what should we do we'll say create a simple rest API with python so that's our message and then for the user ID I'm going to put my user which is going to be brador gmailcom so let's try that out and it might take a couple seconds obviously the the more difficult the the answer the longer it's going to take okay so we got our reply and it has a bunch of you know new line characters and stuff for formatting and we'll we'll when we create our UI with view we'll have this displaying nicely so here's a simple example on how to create a rest API using flask a microweb web framework in Python and it goes through and gives us the steps all right so we know that's working now let's make sure that that got saved to the database so we'll go to Neon and I'm going to go to chats and there it is message create a simple rest API reply there's the reply now since we implemented a database I'd like to add one more route to to get the messages of a specific user okay and we're going to need that for our UI because obviously when you're you know sending messages as a user you only want your messages so let's create a new route we're going to come down here and let's say we want to get chat history for a user so app.
poost and let's see the the endpoint is going to be SLG get- messages and we want to do a sync return promise any okay I'll pass in here our request so request Andre which will be response all right so what I'm going to do first is get it's going to take a user ID so we'll destructure the user ID from request. body because that needs to be sent with the body and then let's check for the user ID or check if not you user ID and if not then we're going to return res. status and we'll do 400 and we'll pass in an error and say user ID is required all right so if the user ID is there then let's open up a try catch and let's create a variable here we'll call it chat history so chat history and then we want to await DB and then we're going to select I'm going to go on the next line here so db.
select and from okay we want to select from chats and let's say where so where and we're going to use EQ here CU we're comparing so we want to to say where the chats. user ID is equal to ID and then we're going to return actually we can just do res res. status 200. Json and let's pass in we'll do messages messages and set that to the history okay and then if there's an error then we're going to res. status 500 and let's uh we'll pass in an error and we'll say internal server error and then I do want to just do a a console log as well so we'll say um actually let's do quotes and say error fetching history and we'll output the error okay so that's our get messages so let's try that out I'm going to come over here post request to SLG get- messages and then we just want the user ID in the body so I'm going to go ahead and send and now it gives me back an array and you see we have id1 user ID message and then the apply I should have my other one here actually no I deleted the other one so let's make another um let's do another chat and then for the message make sure we check that let's say what is the most popular JS framework send as of 20 okay so the 2021 is the cut off for this um it says the most popular JavaScript framework is react all right so now if I were to go back to get Dash messages with the user ID I should have both so create a simple rest API and what is the most popular JS framework okay so we have three routes we can we register a user we use that user to to chat to ask a question to the AI and then we have a an endpoint to to get all the messages of a specific user so that's pretty much it as far as the back end there there's a couple things later on while we're doing the front end that I want to add to the back end but I think that I'll be able to explain it better once we have the UI and I know that backend development like this can be a little tricky and can be a little weird because you don't you're not looking at like a user interface for your are the results of what you're doing you're just seeing a bunch of data so it can be can be tough for for some people so um if you if you've been confused through this don't worry about it I mean it happens as you do more of it it'll kind of Click but now what I'd like to do is jump into the front end create a whole new folder for our our chat AI UI and start to use vuejs okay so now we're going to get into our front end and like I said we're going to be using vue.js version three um we're going to be using a couple other dependencies so let me just show you those real quick so view we're using vit for our Dev server and environment we're using pinf for our state management Library so we'll be able to create a store for our users for our chats uh we'll be able to have our actions and our state in those stores axios I'm using for my HTP Library although if you want to use fetch that's fine too really doesn't matter it's just preference and then Tailwind CSS I'm using for The Styling so we will be be adding quite a bit of Tailwind classes to make it look nice view router we're using the official router for view uh and we're just going to have two routes two pages one is going to be the homepage with the form that has the email and the name so that you can you know enter your name to start chatting and then of course the chat route chat page where you interact with the AI and then typescript which we don't have to set up at all it just works out of the box with vit so those are our frontend dependencies now I have the backend running so you definitely want to have that um this is just something I was testing out but you can see it's mine's running on Port 8000 and then I'm going to go into the chat AI folder and you can see I have the the back end that's what's running over here I want to create a folder alongside of this in my chat AI folder not inside the API folder that's the back end this is completely separ separate so alongside that let's go ahead and run npx and then I'm going to use create V and let's call this chat D ai- UI okay this is the user interface part of our application and then we're going to choose view I'm going to choose typescript although if you you want to use JavaScript that's fine too and I mean even if you don't know typescript it's we're not doing that much so you should be fine and and we already used it in the back end um and it's much easier to set up I mean there really is no setup in the front end it just works so now let's go ahead and CD into chat ai- UI and then let's run our npm npm install to install our initial dependencies that come with v and then we'll install a couple other dependencies as well all right so let's go npm install and view- router we want pinf for our state management and there's also a plugin called uh persisted State and we want to use this because we want our state our user to persist across page loads so we're going to install pinea Das plugin Das persisted State and then also axios so those are our front end those are our regular dependencies and then for Dev dependencies it's just tailwind and the plug-in for V for Tailwind so let's do Dash uppercase D and then Tailwind CSS and then also at uh what is it at Tailwind CSS SLV and Tailwind version 4 is super easy to get set up with v okay so now that we have our dependency set up I'm going to actually just open this folder up in vs code and I'm going to run the dev server from the integrated terminal so from NP say npm run Dev and it's going to be 5173 for the port by default and I'm just going to make this going to just bring this over here make this a little smaller okay so this is just a landing page we're going to get rid of the the boiler plate um what I do want to do is set up Tailwind which is really easy we just need to go into our V config first and we're going to import uh Tailwind CSS from and then it's going to be this at tailwind cssv and then we just need to add the plugin to the array here so Tailwind CSS parentheses and then the only other thing we need to do is go into our main stylesheet so in the source folder I want to go into style CSS and we can get rid of all this other stuff and just simply do at import and then in quotes take Tailwind CSS and that's it and you can see Tailwinds working because there's it's all the same font size there's no padding or or margin on the body so Tailwind is working all right now let's just clear this up a little bit I don't want the hello world component so we can completely delete that okay and then in the app.
view we don't want that I'll leave the script tag there and then in the template uh actually we can get rid of this the scope style and then in the template for now let's just have oops let's just have an H1 and we'll just say my app okay so just kind of clear everything out and in the assets we don't need the view SVG you can get rid of that now I do have a little robot icon and logo that I want to use so let me just find that real quick you guys can get this from the the GitHub repository that that's in the description let me just find it real quick uh let's see Dev I'm just trying to find it off screen where we chat AI UI all right so it's going to be in you have the fabicon which is in the root so just bring that over to your root and then you have um in the source assets folder there's a robot PNG you're going to bring that into your assets folder so it's just this little robot guy all right now to add the fabcon we can go into the index HTML in our um in the root and I'm just going to change the page title to let's do chat Ai and then for the fabicon we'll just add a link and let's change the real to Icon We'll add a type of image slash it's an Ico and then slash favicon Ico and then you should see the little robot in the tab all right so right off the bat I just want to set up routing okay because we're using view router we're going to have the home route we're going to have a chat route so let's start by creating those pages or those views so in the source we're going to create a folder called views and then in there we're going to create a file file called home let's call it home view.
viw Vue and then let's create another file called chat view. viw okay and then I'm just going to have a script tag and then we're going to add our setup so as far as vuejs goes this is not an intro to view I'm not going to explain the the basics um I have a view course A View crash course on YouTube that I just did it like a couple months ago so it's really up to date if you don't know anything or you know very little about VJs I would suggest watching that I mean you can watch it after if you want so you can kind of understand what you did but I would suggest watching it before but basically with the composition API which is a kind of a more Modern Way of of building view components you basically have to have in your script you would export uh a setup function right and then you do all your JavaScript all your state stuff you would do in here but you can do a shortcut by just adding setup here that's why I'm doing that and then I'm also just going to add Lang and since I'm using typescript I'm going to add Lang TS and then I'm not even going to put anything in there for now then we have our template so basically the HTML we want to show on this in this component or in this page which right now I don't really care we'll just do an H1 and we'll just say chat or chat page all right and then for the home view I'm just going to grab that and we'll just change this to homepage all right because I I just want to get these created so that we can create set up our router so we can close those up for now and then for the router we're going to have a folder in the source folder called router and then in that will have a file called index.ts and this is where we set up our routes now to do that we need to import a couple things so first off we need create router from view router and then we also want a function called create web history which allows us to use the the HTML 5 history API to to do routing instead of you know actual page loads and then we also want to bring in any views or any components that we want to load so that would be the home View and that would be the chat view okay then what then what we do is create an array for our routes so we'll set that to an array and each route will have an object with a a path so in this case I want this to be just slash for the homepage and then we can load a component which our views are our components so let's set that to the home View all right and then we'll do the same thing for the chat view so let's make this slash chat and this will be for the component view then what we want to do is export const router so this is what we bring into other files and this is where we want to set this to create router which is going to take in an object with history and we want to set that to the create web history again that's going to use the the HTML 5 history API and that's a function so you want your parenthesis and then you just want to pass in your routes as well all right and that's it for that file now couple other things we need to do before we can actually use our router we need to initialize it in the main.ts file which is basically our entry point so in this file uh let's see we're going to bring in let's bring in in and we want create router uh I'm sorry not create router just router we already used that in our router file that we just created and that's what we're bringing in here so router from.
SL router now we have to use that so where we have this create app which bootstraps the entire application it mounts it to this this element with app um I'm going to just put this in a variable and then we'll mount it down below so we'll take this and we'll do app. Mount here instead and that way we can take that app that app object and we can call use and then we can use the router okay so we got that done now the last thing to be able to see the routes on the page in the main app.
view where we have this H1 we want to replace that with router View save that and now we see homepage because we're on the the Home Route if I go to SL chat then we're on the chat page and if you want to create just a quick navigation we can do nav and then we can use router link okay so router link we can add a two attribute here to slash and then we'll have one to chat chat and then we should be able to click on chat takes us to the chat page home takes us to the the homepage now we do need to set up our store but before we do that let's just get the form displayed on the hom page uh and we can get rid of this nav we don't need that okay so let's go into Let's see we want to go into the home View and I'm going to bring in the that robot image because that's going to be our logo so let's import robot image from and then it's going to be dot dot slass assets slash and then robot.png okay so we'll bring that in and then let's just start to add some of the the elements down here and use our Tailwind classes so we're going to have a div that wraps everything get rid of this um div and then for classes here we're going to do h- screen let's make this a flex box and align everything to the center so items Das Center and justify Center I'm not going to explain what every Tailwind class does I have Tailwind crash courses I have a premium course if you want that but it's pretty obvious what most of these classes do background we're going to make gray let's do 900 for the shade and then we're going to do text white okay so that just gives us this dark background then inside that I'm going to have another div with a class of pad let's do padding 8 and I'm going to do BG gray 800 make get a little lighter and rounded large let's do shadow shadow large and let's make it width Dash full and a Max width of medium all right whoops I don't know what what happened oh need to do this all right so there's our container for the form so in that div let's have an H1 we'll do text Dash let's do 2XL for the sizing we'll say font Das semibold let's do uh margin bottom four and text Center and in that we'll say welcome to chat AI all right oh I forgot the robot so let's actually put above the the H1 I'm gonna have my image now since the source is going to be pointed to a variable right it's Dynamic we need to bind it so we could either do a v-h on or we can just put a colon here and then set it to something Dynamic such as the robot image variable and then I'm just going to add a couple classes on this as well so let's do MX so margin on the X Access Auto width 24 height 24 and then let's do a margin bottom four and there we go so now I have the little robot guy and then let's go under the H1 and we want to have our inputs so for the classes here we're going to do Dash uh with Dash full let's do padding two for margin bottom two and then I'm going to do a BG gray 700 so make it a little lighter the text will be white um let's say round rounded Das large and then I'm also going to add a focus style so on Focus I want outline Das none okay uh yeah and then let's add a couple other things so in addition to whoops what did I do here that should be there so I want to add a placeholder and it's going to say name and then we want to buy this name to uh a reactive variable we want to we want to have a a piece of component State called name and we do that with v- model and we we'll set that name and we want to create that name variable up top here in the script so let's say con name and we set that to ref okay we're creating a reactive value so ref and then whatever the default is will go in here which is going to be an empty string now that ref we do have to import that from view so let's bring that in that should be lowercase R okay there we go so now that gets bound to that if I put in you know hello here it's going to show here because that is bound to that input okay and then we'll have some other values here as well like the the email and let's see do I want to add the rest of the stuff now um yeah uh might as well just copy this down so we're going to have a loading state so basically when we reach out to our API we're going to set loading to true and then when we get the result it'll be set to back to false so let's set this to ref default value will be false um and then I also want for ER if we have an error I want to have that in our state as well that'll just be an empty string by default as well and then let's come back down let's create our email input so I'm going to take this copy it down let's change the type to email and let's see we'll change placeholder to email and the V model to email so now this input is going to pertain or is going to be bound to this variable if I save it we see the email and then let's create the button okay so right here let's say say button and as far as classes go let's do with- full let's do padding to we'll do BG blue Das 500 and rounded large all right and inside that I want it to say start chat but if it's loading then I want it to show logging in okay and it's not actually a login but you know what I mean creating the user or just getting the user so if you want to show something Dynamic uh within your view template you use double curly braces so here I can put a JavaScript expression like if it's loading then show logging in dot dot dot else then show start chat so now we have our start chat button and then I also want to make this button disabled if loading is true so it's going to be um Dynamic so I'm going to do colon disabled because what I'm setting this to is a is a variable right it's loading so if I were to set loading up here I know a lot of you guys know this stuff but for those of you that are kind of new to view if I set that now it's disabled and it says logging in so I'll set that back to false all right now let's see um for the error I want to show that down here in a paragraph So in the paragraph we can use a v if directive which is just like an if statement whatever I put in here in here will only show if this is true so for V if we just want to set that to error so if error is true then I just want to show the actual error and we'll just add a class uh let's add a class of text Dash red we'll do red 400 and text Center and let's do margin top two okay so if I have an error which we can test out by just putting something in here then it will show like that all right cool now that button is going to call a function so let's go to the button here we'll say at click so when we click this we're going to call call a function called create user which doesn't exist yet so we're going to go up here and we want to create we want to create the create user function so here let's say const create user we'll set that to async an async function and let's let's check for the the name and email so we'll say if not name and we can access the value with DOT value or if not email.
value okay so if either one of those are not you know not added then I want to set an error so we'll say error. value and we'll set that to let's say name and email are required and then we'll just return okay and then I think you know what what I think that's as far as I want to go because we don't have our store yet cuz what we're going to do is send a request to well we could you know what we'll send the request I'm trying to think of how I want how the order I want to do this in do we want to do the store first yeah you know what before we do the request let's do the store I mean we can test out this little validation if I were to click Start chat without putting anything then it's going to give us an error but yeah let's create our store so so basically when the data comes back from SL register user from our back end it's going to be stored in our user store which we have yet to create so we're using pinea which means we have to initialize it so we're going to go into our main.ts which is right here and couple things we need to do um yeah we'll go right here and let's import here create pinea from pinea and then we also need that plugin which is pinea plugin persisted State that's going to come from oops it's going to come from uh this right here okay so we want to bring those in and then let's go above this app let's say const pinea set that to the create pinea function and then we should be able to take that pinea object and say do use and we can use the plugin so pinea plugin persisted State we want to pass that in and then the only other thing we need to do is use it just like we did the router so copy that down and pass in pinea okay I don't have the code right in front of me but I'm pretty sure that's that's right all right so we'll close that up now to create our store let's go into the source folder create a folder called stores and for each resource we'll have a file so I want to create a file called user.
TS so this is where our Global State goes as well as any actions which are going to be functions that mutate the state in some way um so what we're going to do is import Define store and that's going to be from pinea all right and then we're going to export let's export const and we're going to call this use user store and we want to set that to that defined store and then that's going to take in a name of our of our store so user and then we pass in an object and this is where we can Define…
Transcript truncated. Watch the full video for the complete content.
More from Traversy Media
Get daily recaps from
Traversy Media
AI-powered summaries delivered to your inbox. Save hours every week while staying fully informed.









