How To Create A Social Media App Using The T3 Stack - Next.js, React, Tailwind, Prisma, TypeScript
Key Takeaways
This video demonstrates how to create a social media app using the T3 stack, which includes Next.js, React, Tailwind, Prisma, and TypeScript. The video covers setting up the project, generating boilerplate code, creating a database, and deploying the app to production.
Full Transcript
this is going to be a massive project not only am I going to show you how to create this Twitter clone which includes everything you would want such as authentication creating tweets liking tweets following people different feeds and so on but also I'm going to show you how you can actually deploy this in a production ready way so that people can start using it immediately [Music] if you want to build out a robust backend API that supports things like rest graphql authentication and so much more but you don't want to go through the monotony of writing out a bunch of really boring boilerplate code then look no further than today's video sponsor amplication as you can see they make it incredibly easy to get started with a backend API you just click a few buttons to select what you want and it's going to generate all of the code for you to set up a full backend API with an admin dashboard and it uses all the technologies that I really love such as Prisma jest react and so on which is really great best of all application is completely open source which I love and also the code that it generates for you is really easy to read and understand so you can always go ahead and make changes to the actual generated code but the thing that really sets application apart is that they make it incredibly easy to modify your code inside of their actual UI so you can go ahead and add relations to your data and anything else that you want to build a query on your data inside of the API and it's all incredibly easy and it's all inner graded perfectly with GitHub so it works just like your normal code workflow so this is just a super power essentially that you can use to make writing out of some of these boilerplate codes so much easier if this sounds interesting to you I'm gonna have a link in the description to amplication you can get started completely for free they have a great free tier so I highly recommend checking that out welcome back to web dev simplified my name is Kyle and my job is to simplify the web for you so you can start building your dream project sooner and to get started with this Twitter clone we're actually going to be using something called the T3 stack this is essentially built on top of next JS and really all the T3 stack does is it combines together different Technologies into next JS so you have nexjs which is the main thing you have typescript so everything is going to be typesafe we have Prisma for handling all of our database related needs and trpc is going to be used for handling all of our different needs for communicating between the client and the back end we also have next auth for authentication so it pretty much includes everything you need out of the box to create a type saved application so to get started we can just copy this command bring it over to our tournament and run npm and create t3-app at latest so we can just run that real quick and it's going to ask us a few things to get started with so let me just make this a little bit larger so you can see first of all we need to install the latest version so let's do that real quick and then after that all we need to do is just answer some questions so what is our project going to be called I'm going to put a period because I want to create it in the current folder but you can put whatever your project is we're going to be using typescript and here we can toggle what we want in our case I want to use everything so Tailwind is the other kind of main thing that T3 has inside of it which I really love so we're going to toggle all these hit enter and then of course I want to initialize a git repository so we'll just say yes but I like to write npm install yep and then my import Alias I'll just leave it as the default so this is just going to go ahead install everything create all the boilerplate for us and you'll notice that there's a lot of stuff that this actually creates for us I'll go through all the stuff that you really need to understand about it as we go through this tutorial but understanding what every single file does is not super important now that that is finished running you'll notice that there's two steps we need to do we need to First push our database and then we need to run some Dev command here to actually get it up and started now the very first thing that you'll notice if we go into this Prisma folder this is where our database stuff is defined and we open this up you'll notice that the provider here is SQL Lite this is fine for developing locally at the beginning but really you want to use a more robust database for your actual development especially when you post to production and in our case what we're going to be using is we're going to be using something called Planet scale if you've seen some videos by Theo he talks a lot about this essentially it's a really easy to use database that you can host online you can also host your own locally if you want but since we're going to be dealing with production as well I just wanted to host everything in the exact same place so what I'm going to do to get started you'll notice I currently have a database here that's what I was using for testing I'm actually going to go ahead and delete this so I'm just going to go into the settings I'm going to completely remove this delete this database yes let's delete T3 Dev there we go and now what I want to do is I want to create a brand new database so we're just going to come down here to create a database and we're just going to call this Twitter clone and then for the region I'm going to be using the US East that's relatively close to where I live so it'll be the fastest for this tutorial and it's also close to where we're going to be hosting our actual next.js application which is really important so we'll click create database here and now we have a database up and running and the really nice thing about planet scale just make this full screen real quick for you is that it has something called branches so we can have a production and a development branch that we can both have running on the same place so it's really easy to do production and development so for example I have this main branch here and what I want to do is I want to create a brand new Branch off of that main branch but first we have to wait for this to initialize so I'll come back to when that's done there we go that just finished and what I want to do right here is I want to promote this to a production Branch essentially what I'm saying is that this is going to be our production server Branch right here and then I'm going to create a branch off of that that's going to be for development I'm going to come in here I'm going to create a brand new Branch I'm going to call this one Dev and I'm going to base it off of our main range hosted in the exact same region click create and now if I go back here you'll notice we have two branches we have this Dev Branch right here and the main branch the main branch is going to be our production Branch where we're actually running our production server and Dev is going to be where we do all of our development and the nice thing is is census's branches it works just like git where I can essentially create a deploy request which is like a pull request to make my changes from my Dev you know environment here to my production environment so if I make database changes I can push those to production really easily so we go back into Dev here we need to wait for this to initialize I'll get back with you when that's done there we go that just finished and what we can do is we can come over here and click on connect if we open this up it's going to say that we can connect using different things as you can see here we have Prisma is the option that's being chosen by default but there's a ton of different options and I want to connect with Prisma so I'm just going to click the copy button to copy over this database URL and this needs to go in our environment variables file so if we come in here you're going to notice our database URL we're just going to completely replace that now you will notice that this has password and username information inside of it so right here you can see that I have like a password you do not want to expose this data anywhere because if someone has access to this they have access to your database which is definitely not a good thing so make sure that this is always hidden in some type of environment variable so it's not exposed to other people because if they have this again they can directly access your database I'm going to be completely deleting this database when I'm done with this tutorial so you won't be able to access this you know password information here but just make sure you don't expose this anywhere and if you do you have to reset it so with that done we can go over to the schema section I'm going to copy this as well and bring it into my schema here what I'm going to do is I'm just going to paste this down and you'll notice this gives us a client and it gives us a DB right here and down here you'll notice we have a client we can just replace this and same with this DB the only thing is here it says when using post SQL or MySQL which in our case we're using MySQL make sure you uncomment the at DB text annotations so I'll show you exactly what that means we'll just get rid of all this real quick we'll scroll down a ways you'll see right here these sections that have at DB text just make sure that these are uncommented like that and now if we give this a quick save that should hopefully fix those problems now you did notice if we scroll down a little ways and we hover over this you're seeing that here it says with relation mode equal to Prisma no foreign keys are used to release your Fields would not benefit from the index essentially it's saying it can't create an index for you and you need to manually create an index that's just because of the way that planet scale works so what we can do is we can actually create our index for that so if I make this a little bit larger so you can see this is for our user field so I could just say at index and this index is going to be for my user ID and I want to make sure this is a double Ampersand like that indexes are just a way to make it so you can easily query data in an efficient way so I'm just adding an index to this if we scroll down you're going to notice we get the exact same thing here for this user so I'm going to create the exact same Index right there and that should hopefully clean up all those different warnings for us so now if we give this a quick save we should be able to run npx Prisma DB push and that'll actually push all of these database changes that come by default for things like an account and so on it's going to push it to our database over here on planet scale if we just give this a quick refresh here we might have to refresh our entire page you can see it says the schema diff is being generated it let's just give it a quick second but hopefully it should actually show us information there we go it's saying that all of these changes essentially are the difference between our development branch and our main production Branch so you can see here we have all this you know SQL here for creating all of these different tables so now we've essentially taken this entire Prisma schema which is our entire database and we've pushed it up to this development Branch so we can start using and accessing it which is great now also if you're not familiar with some of the technology in this stack for example Prisma I have an entire crash course covering Prisma I'll link in the cards and description for you it's a rather long video but it covers everything you need to know about Prisma so I highly recommend checking it out now with that done we should hopefully be able to run our actual application so if we say npm run Dev that should hopefully start up our application and we can see if everything is working so let's open that up real quick give it a quick second to load and hopefully it's not going to give us any errors and it's just going to show up all the information for all the default stuff which is inside of this Source folder here as you can see we have it showing up here it's loading our information hello from trpc and then we can click sign in to sign in with Discord now currently this is not going to work because if we look at our environment variables you'll notice we don't have all of our environment variables filled in so we need to finish doing that but of course that's the next step here so in order to hook up Discord you need to go over to discord.com developers slash applications if you just search for Discord Dev applications that should bring you to here and now you have the ability to create a new application we're going to essentially need to create two applications one for development one for production so we're just going to do the development one for now so we can come up here and we can name whatever this wants so we'll call this uh Twitter clone and we're going to make sure that this is for development only so we'll say Dev and we can click create now we don't really need to do anything with this other than go over this oauth 2 tab this has our client ID which we can copy and paste into our secrets file here and then I'll has our client secret which we can just regenerate and if I just enter my two-factor authentication code you can see we have a client secret here that we can use and we can paste into here again this secret code is something you should never share I'm going to be deleting all this after this video goes live so you won't be able to use any of it just make sure you don't ever share this with anyone and if it does get exposed just click the reset button and create a brand new one so that is all we need to do for the Discord client ID and secret so hopefully everything should be working for the actual authentication portion and if we click sign in you can see that it is going to somewhat work but we have one last thing we need to do and that is add a redirect and that's because whenever we're dealing with authentication we need to be able to redirect the user back to the page that is our application that's the way oauth works so we need to actually tell them what that redirect URL is going to be so the best thing we can do is if we go back to the documentation for T3 there's a section on next auth and you'll notice it has setting up the default Discord provider which is what we're using we already got the client ID and the client secret setup all we need to do is add the redirect so what we can do is we can just copy this URL essentially so I'm just going to copy this URL right here and that's the URL that we're going to be using and I'm just going to paste that right here into our redirects and we'll click that that is going to be added so we'll click save and now we actually have that redirect set up so now what we can do is we're just going to reset our server real quick to make sure that all the different environment changes that we made actually go through I'm just going to go to our default page right here localhost 3000 I'm going to click sign in sign in with Discord and hopefully this will bring us to a page right here it's saying that I want to be able to access Discord with my Discord user I'll click authorize give it a quick second and hopefully it's going to create an account for me and as you can see I'm logged in as web dev simplified and I can see the secret message because now I'm logged in now that is great there is one thing you'll notice if we just scroll up here a little ways inside of our console we're going to get this warning that says knocks next auth warn no secret essentially we don't have a secret right here here this is really easy to fix we can just copy this line right here to generate a random set of characters you can see that that's a random set of characters we can just paste that in as our secret and uncomment that line and now we have a secret generated which is just going to be a little bit safer again if this gets exposed you're gonna have to regenerate it again again just keep anything secret secret which is why it's in these EnV variable files that don't get committed so now with that done we essentially have everything we need to do to get set up with authentication and our database the next thing I want to do is actually deploy this right away so that we can really easily get it deployed and we can test what it's going to look like in production as well as in development so the very first thing that you need to do to actually get this deployed is to go to GitHub and create a brand new repository like this go through make it public whatever you want to do and then click create repository I have a simple command setup that allows me to do this automatically it's called GH init video repo I create a ton of GitHub repositories for my videos so this just essentially goes through creates a repository for me pushes all my code to it and gives me a license as well as a URL so if I open this up I now have a brand new GitHub repository with all the code that we have inside of it so super straightforward and it also generates a license for me but for you you can just go ahead create a GitHub repository copy the code that it tells you to use paste it into your console and you can have all your code pushed up to here rather simply from here we can go to verse cell and this is where we can actually create our application you can see here I have the test version right here so let's just add a brand new project to get this working and we're going to import a git repository now the way I have my GitHub set up is I only give Versa access to specific repositories so if I adjust my permissions what I can do is come into here make sure I give it my password and everything and then I can scroll down to wherever the permission section is and I can select a specific repository which in our case is our Twitter clone I'm just going to use that one click save and now it has access to that repository as well so now we can just click import you can see we have Twitter clone here all of the build information should essentially be the default but we need to set some environment variables for things like our database as well as things like our secret our next auth URL our client ID and this secret here so the very first thing that we can do is we can go ahead and get our database URL so if we go back over to Planet scale go to our branches you'll notice we have our production Branch we can come into here click connect and now we have a URL here for our database URL that is for our actual production database so we're just going to click copy or copy on that sorry come over to here paste that down and you can see it has created that right there for us the next one we have is going to be for our next Us Secret I'm just going to generate a brand new secret using that same command this is going to be a new secret that is only used in production there we go let's add that along next thing we have is our next auth URL the next auth URL is whatever the URL of our application is right now we don't know what that is because I don't have a custom domain so we'll leave that blank for now next we need our Discord client ID so if we go over to Discord we just want to create a brand new application so we can come back to our applications create a new one I'm going to call this Twitter clone and this one is going to be for production and we just go through the exact same steps we did for the development one come over to the oauth section copy over our client ID and we'll paste that down as our value then we're going to do our client secret and we're going to come back over to Discord again there it is reset our secret make sure we enter in that two-factor authentication code click submit and then we're just going to copy that over as well and again make sure you don't expose any of this information now with that done we should have everything we need to done to click deploy here it's going to take a little while but it's actually going to deploy our application and then once it's done deploying what we can do is we can actually take that URL that we get generated as our automatic URL and we can use that URL not only in our Discord redirect here but we can also use it inside of our environment variables for the next auth URL as well so once that's done I'll come back and show you there we go we can click continue to dashboard here and that should give us our URL so if we just click visit you can see we have our URL up here I'm just going to copy this URL and this is what we're going to use as our environment variable so we just need to make sure we go to the settings we need to go to the environment variable Tab and for our next underscore auth or I'm sorry next auth underscore URL we're just going to paste in that value as well now we can click save on that go over to Discord we need to do the exact same thing and we need to make sure we include all the additional information on the end of it so if we just go back to the docs you can see that that is let's just copy this real quick there we go paste it down and get rid of all the stuff at the beginning there we go it's just slash API slash callback slash Discord and click save and now hopefully everything is also working on our production version so here's our local version here's our production version let's give it a quick refresh click sign in and see if this works we'll sign in with Discord we'll click authorize and if everything works well well it looks like we have an error of some form the reason for this error is because we haven't actually pushed up our production database right now we just have our database completely blank right now so what we want to do is we're going to turn on this thing called safe migrations you can see safe migration is not enabled we're just going to enable that real quick and that allows us to really easily migrate from our development Branch to our actual production Branch so we go back to all of our branches Off full screen this again we can click on development here and you can see all these changes that we have in our development we want to also push to our production I'm going to click create deploy request and what that's going to do is create this request you can see it looks a lot like a pull request and it'll allow us to actually deploy these changes so I can just click deploy changes and what that's going to do is it's going to deploy all these changes to our production database once that's done are actual authentication should work because the reason it was failing is because we didn't have any tables in our database so obviously it couldn't save our information and there we go the deployment just finished so hopefully now if we go back to here we try to sign in with Discord our database will actually have tables inside of it and there we go it can save the user in the database and you can see just how quick everything is the reason everything is so quick is our database is deployed On Us East and inside of here are functions if we go to the functions you can see by default they are also deployed on the east coast of us so our actual functions which access our database are as close together as possible which is really what you want if I were to move these to somewhere else for example I deployed my functions all the way in Singapore it's going to be much much slower because now my database is on the other side of the world from where my actual application is running now with all of that done we can essentially close out of everything because we now have our production environment set up as well as our development environment setup and it's going to be very easy for us to push changes from development to production whenever we want to I'm going to close out of pretty much everything except for I'm going going to leave open our development server here as well as our database for changing those changes and then versl so we can actually check our deployed changes now the very first thing that I want to do is I want to set up our schema for our entire database so we just have everything done that we need first of all we don't need this example table this is just for example purposes what we want to do is we want to create the different models for the tables that we're going to have so in our case we're going to have an ability to create a tweet and another model is going to be the ability to create a like so it's coming here for a like as well now a tweet obviously needs to have some type of ID so we're going to give an ID in our case I'm going to be using a uuid so we're going to set the default to uuid which is why I gave this a column type of string here next we're going to need to have a user ID for someone that actually creates this and that's going to be a string because if we go down here to our user you can see that they're using strings for the IDS as well then what we can do is we can go ahead and put some content inside of here that's going to be a string for whatever our content is are created at here is going to be a date time and that is going to default to whatever the current time is and I normally would put something like an updated ad on here but since we can't edit our Tweets we're not going to be doing that because Twitter doesn't allow you to edit tweets at least if you don't have you know fancy stuff that you pay for so in our case we're not going to be doing any of that stuff so we give this a quick save now what we need to do is actually set up our relations between the two so first of all what we can do is we can say each tweet has a user and a user is a type of user so we're mapping to that user type and we're saying that this is a relationship a relationship that is going to be mapping on the field user ID and that field references the ID field inside of our user table and importantly whenever I delete a user I want to also delete all the tweets that that user created as well now again I'm getting that same error where it's saying that there's no indexing created so I want to create an index here for my user ID just to make sure I don't have that error show up also if I come down all the way here to where my user is you're going to notice it created this row right here I'm just going to change this to tweets instead of a uppercase tweet and there we go now it's going to be an array of tweets that we can access if I come back up to here and from here what we want to do is Define our actual like so instead of our like we're going to have a user ID which is a string and we're going to have a tweet ID which is also a string there we go and instead of specifying an ID on I like I know that a user can only like an individual to read once which means that if a user ID and a tweet ID there's never going to be more than one record in our database that have the same user ID and the same tweet ID so I know that these two are unique when used together so what I can do is I can say our ID is just going to be the combination of our user ID and our tweet ID just like that since these two are always going to be unique from one another also I can get my user just like this by doing that same relation stuff so we can do Fields is going to be user ID we can make sure we reference our ID and again I'm going to do a simple on delete of cascade since if I delete the user I'm going to delete their likes as well I'm going to do the same thing with a tweet so here it's going to say tweet this is our tweet ID it references the ID and I'm going to do the same thing with deletion so if I delete the tweet I obviously can delete all the IDS associated with it then I can create my indexes one for user ID and one for tweet ID just like that if I give this a save it's going to automatically put my likes in here I'm going to call this likes just like that and then down here inside my user it's doing the same thing I'm going to call this likes as well there we go now the very last thing that we need to do for our user I'm actually going to put a comment here that just essentially says non-next off because this is stuff that's not related to next talk the last thing we need to do is actually be able to follow users and this is a many-to-many relationship because a user can follow many other users and they can be followed by many users as well so this is actually rather easy to set up inside of Prisma we can just say that we're going to have some followers and that's going to be a user array and we can just set up a relation and we can say that the name here is going to be followers just like that I can do the exact same thing with some follows and these are the people so we have people that we're following or the people that are following us as well as the people we are following just like that and now by giving these relations the same name we're essentially saying that they are linked up to one another so all the followers of one user you know they're linked up to the follows of the other user that they're actually following and normally you would need a table in the middle to actually hook this up but Prisma automatically creates that join table for you which is really nice so we can write these two simple lines and now we automatically have the ability to follow different user now with that done we can go ahead and we can actually push these changes to our real database so we can say npx Prisma DB push that's going to push all the changes from our schema up to our planet scale development database and if we come in here and I just make this a little bit larger go to our branches go to Dev we should hopefully see that it's going to have some changes inside of here as you can see there we go it just loaded we have dropped some tables which is the example table we've created some tables for our followers in the joining our like and our tweet so it's making all of these changes for us and we can create a deploy request to put this up to production if we want which in our case why not let's go ahead and do that so we'll just set that up I'll click deploy changes there we go so now it's going to deploy those and in the background those will be done while we're working on the rest of our project now from here we can go ahead and actually start working on some of the more fun stuff which is going to be dealing with our react application and xjs code so let's say npm run Dev to get it started up on development close out of prismex we don't need to deal with the database and inside of here for our Pages we can go into our underscore app page and this is essentially our root of our entire application now inside of here we don't really want to modify too much all we want to do is change what we're rendering inside of this section here this component right here just allows you to render all of your children but we want to render some stuff around them as well because the way Twitter works is that they're going to have a sidebar on the side also I want to be able to have a head component that has things like our title so I'd come in here and I can say head and that's going to be coming from our next head and inside of here I can say that our title is just going to be Twitter clone and then we can you know give it a description for example so I can come in here with a meta tag we can say meta name equals description and let's say content here is equal to this is a Twitter clone by web dev simplified you know it doesn't really matter what this says so now what we can do is we can actually go into our index page because right now they have the head inside of here also let's get this link for our favicon we'll put that in here as well but inside of our index we'll get rid of this head inside of here and we'll actually get rid of all of the content inside this entire page and we're just going to replace this with a single H1 that says hi just so we can see if we're on this page I'm going to get rid of this query go to the API get rid of all that stuff and I'm going to get rid of this entire auth showcase as well we're just going to completely remove that and remove all of this so overall this page has almost nothing inside of it if we come over here you can see it just has the text high and you'll also notice it says Twitter clone at the top which means it's using this head element right here now from here what I want to do is I want to wrap everything inside of a div which is going to be our container so we can give a class name of container just like that I can also say I want to Center this by saying our MX is going to be Auto and let's make this display Flex as well for how we're going to lay out the rest of the content inside of here so for now we can just put our component in there and just by doing doing that if I zoom out here and I make my page a little wider you'll notice that now everything is slightly indented from the side that's what that container class is doing for us and what we can also do is we can say we want to create a side nav and that's because inside of Twitter we're going to have a sidebar so we have a side nav component it's currently not created at all we're just going to leave that as is for now and the next thing I want to do is actually create all of our main section and that's going to be inside this div which we're going to give a quick class name here which is going to be Min H is going to be screen so it's automatically going to fill the full screen height if possible our Flex glow grow here is going to be set so that it's going to take up as much space as possible and then we want some border on the left and the right so we'll say Border X and with that done if we just comment outside now for now you'll notice we have borders on the left and the right hand side it's a little bit tough to see because they're rather thin but they are there for us and that works just like Twitter does obviously the next thing is going to be our side navigation so to create this what we want to do inside of our source we'll create a components folder and inside of here we're just going to say that we want to create a new file called side nav.tsx and what we can do is export the function called side nav and we can just return an H1 that says nav for now and then inside of here we can make sure that we import that just like that and you can see it's importing it right up here so give that a save you can now see our nav is showing up on the left hand side now if we jump into that side nav we can start giving it some Styles so I'm going to remove that text we're going to use a nav here I'm going to give it some classes on it and we know for a fact we want this to be sticky to the top so we'll say sticky and top zero and we want to make sure that this is aligned to the start of our page because it is currently inside of a flux container if we just go over to our site or our app here you can see that we are inside of a flux container so we want to make sure that this is stuck to the top of our Flex container that's going to work fine we can also I guess say align items I'm sorry it's just called items start that's going to do the same thing so we don't even need to have this right here then what we can do is we can add some padding so we'll say px2 and we'll say p y is going to be 4. give that a quick save you'll notice currently it has nothing inside of it if I say hi you can see that that has its padding and everything set up which is great so now with that done we can come into here we can say that we're going to have a UL because this is essentially going to be a list of items I'm going to give them some classes as well I want this to be using flexbox I'm then going to say I'm going to be using columns for this so we're going to say Flex column we're going to use items start on this as well as gap2 and then I also want to make sure my white space doesn't wrap at all so there we go really what these Styles have done is give us something that stacks on top of each other everything is aligned to the left hand side and we give it a little bit of space in between now we can do is go through each one of our Li's and inside of these we just want to have a really basic link we're going to be using our next link for that so for example we're going to have a link that goes to our home page and for our link we're just going to say href is equal to home just like that so now we have our home link I can copy this down one more time and we're going to have a link for going to our individual profile as well so for this one we need to make sure that our href is based on our actual user ID so we can say profiles slash because that's the route we're going to do essentially in our Pages here we're going to create a new folder called profiles and then inside of that we're going to create a file called bracket ID bracket.tsx and that essentially gives us a route to this URL so if we put an ID inside of here that's where it's going to route to so this is going to be something like user.id we just need to get that user.id so to do that is actually really easy we can come all the way up here we can say our const session is equal to use session and this comes from next auth and this session has a user on it so we can get say const user equals session dot data Dot and you can see we have user here and this is sometimes going to be there and sometimes not if we're logged in we're going to have the user and if we're not logged in obviously there is no user so we can use that user to get the ID here and we only only want to render this link if our user is not equal to null so if our user is not equal to no then we're going to render out the link to go to our profile So currently we're logged in so we have this profile link and if I click on that you can see it goes to slash profile slash and whatever the ID of that user is now this page doesn't export anything so right now that's why we're getting an error so we can just close out of that and come back to here next we want to have our login and log out links so for that we can just do again a check here if our user is equal to null then we want to render our log out link so if they're equal to null we're going to come in here and render out the logout link otherwise we're going to render the login link down below it so we'll just put null for both of these for now and the first one I want to tackle is going to be the login link so we can put that instead of An Li kind of like we've done here but instead of using a button or instead of using a link I'm sorry we're going to be using a button just like this make sure I spell button correctly and this is going to be called log out there we go we're going to have it on click here that is going to log our user out so how exactly do we get that well there's a function called sign out that we can get from next auth so you can see we imported that up here and that'll sign our user out for us now because we're using typescript and it's rather strict we essentially need to say we don't care about the return so we can just say void the sign out here and it's going to say that we don't care about whatever the return value of this is I want to do essentially the exact same thing for sign in so we can get the sign in function this will just say log in instead so now you can see we have the login button if the user currently exists so right now I have this flopped if our user is null we want to log the user in and if they are not null we want to log them out so I just have these swapped this will say sign in and this will say sign out there we go so now you can see I click log out right here and it's going to log my user out but it doesn't look like it's quite working the reason this isn't working is because on click is trying to pass the event argument to sign out which is causing it to fail so instead we just need to define the function like this and we do the same exact thing with sign in there we go so now when I click log out you can see it logs me out and I click log in brings me to that page where I can sign in with Discord I can click authorize and boom there we go I'm signed in as web dev simplified now there's a lot of stuff I can do four styles of these different links but for now I'm just going to leave that to later because it's kind of boring compared to some of the more interesting stuff like actually getting the Twitter clone to work one thing I did miss though if we go into our app here there's one additional style that we should add onto this div right here just to add some spacing on the right so we'll say small pr4 that's going to add some padding on the right whenever it's a small screen or a larger so if I zoom out to a more normal screen size here I shrink this down you're going to notice that our sidebar over here for our border there's just a little bit of padding on the side it just looks a little bit better to actually be able to see that border but obviously on a smaller screen or when I'm super zoomed in like this obviously we don't need that that's why I made sure this only shows up on those smart or on the larger screen sorry so now what we can do is we can go to this index page here and actually implement this bulk section in the middle because on Twitter we have a few different things we want to do we want to be able to create some tweet as well as display all the tweets at the bottom so let's go ahead and get started by just creating a header so first I'm going to do some empty tags here because we're going to have multiple things we want to return with the first one being our header and this header is going to have a bunch of classes applied to it so we want this to be sticky as well at the top so top zero and we want to make sure it shows up above everything so we'll give it a z index of 10. also we're going to give it some border on the bottom because everything in Twitter has all these borders around it we're going to make sure the background is white and we're going to add some padding on the top of it as well and inside of the header is where we can actually put our header which will go inside of an H1 it'll just say home now all we need to do is add some class names to that as well so we'll say margin bottom is 2 to give it a little space the x is going to be four again spacing things out we'll make the text a little bit larger and we're going to make it bold so now you can see it says home right there and if our page scrolled you'll see that this will follow our page down as we go so that's really what we need to do for our header section so now we can move on to the section for a new tweet form I'm actually going to create a custom component for this just like that so we can use this anywhere we want so this is going to be for creating a brand new tweet we'll put it right inside of here new tweet form dot TSX there we go export function new tweet form and inside of this page we can just do a quick import on that there we go so now if we just make sure that this actually returns something it'll now say new just like that so inside of this new tweet form let's just go ahead and get some of our jsx in place before we start focusing on a bunch of logic first of all we're going to have our form which is going to have a bunch of classes on it as per usual so we're going to come in here and say we have flex and we want this to be a column based Flex layout our Gap is going to be two and we're going to have some border on the bottom as well as some similar spacing of PX4 and py2 if I just put some text inside of here you can see that now we have that spacing as well as that border now the next thing I want to do inside of here is I want to create a div that's going to be essentially a row for our form this is going to contain where our text information is going to go as well as our profile image then below that we're going to have an actual button for whatever we want so this is going to be a button down here and then this right here is going to be where we actually put our text area so the first thing I want to do is style out our text area we're going to give this a class name again of flex because I do everything pretty much with flexbox I will say it'll have a gap of four and that's because there'll be two things there's going to be a profile image which I'm actually going to create a custom component for we're going to use that literally everywhere and it's going to take in a source which is whatever our user you know URL is for now we'll just say URL doesn't matter whatever it is and then we're going to have our text area and this is actually going to be where we input all of our information for our actual code so if we just comment out profile image for now and save you can see we have a text area and we have our button down here so that is working now for our text area we can give it some Styles so we can say our class name here is going to be Flex grow we want to be able to not be resized so we'll say resize none because we're going to handle that automatically we're going to make sure our overflow is hidden that'll help us with that automatic resizing and then we're going to give it some padding as well as make the text inside of here a little bit larger and remove any outline that is on it now if we give that a quick save you'll notice it's essentially invisible and even when I click on it it's invisible that's how the actual Twitter one is it's kind of weird but that's how it works but you can see as we enter some text inside of here it's limited to its specific size but obviously we can make it bigger or smaller automatically inside the code also I'm going to give this a placeholder and inside of Twitter theirs says what's happening so that is what we're going to put inside of ours as well so now if we give this a refresh you can see we have that text and we can click inside of there now the next thing I want to work on is our button and I'm actually going to use a custom component for this so let's create a brand new component called button.tsx because pretty much all of our buttons are going to follow a similar layout inside of our code so we'll export that function here we'll just return a button just like that come into here and we'll make sure that we import that oops button there we go import that perfect and this is just going to say tweet there we go I think that's what it says on Twitter and now we can go over to our button and we can get all the different props that we want from it so for this button we know that we have a few props that we want to add that are custom as well as a bunch of other props which are going to be button specific so here I can put all of our button specific props just like that and then we can follow it up with our custom props that we need for example I'm going to have a prop called small as well as gray to determine if this button is a grayscale and if it's going to be large or small also I want to add the ability to pass in custom class names as well there we go so now it's actually created the type for our button props there we go and we're going to set this to that button props if we save this real quick we know that small here is going to be a Boolean we know that gray is also a Boolean we also know that class name is going to be an optional string and technically all of these properties are optional so this is optional this is optional they have default values of false you don't need to explicitly put them but I kind of like to and then what I want to do is I want to make sure that this has the same properties as a button inside of react if I hover this button you can see right here exactly what those props are so I'm just going to copy this and I can just say right here Ampersand of that now if I just make sure I import everything properly add that import and we're going to add that Import in and if we add that last angle bracket in and we give this a save make sure we import only the types from this now we actually have it so that the props are being properly imported which means inside of this new tweet I can set any normal prop that I could set on a button for example I could set an on click property if I wanted now to style out our button we need to do quite a few things so we need to create some different classes so I'm going to have some classes that are based on size so we'll say size classes is equal to and if we are small we're going to have certain classes which are going to be px2 and py1 and if we are a large button I am instead going to have PX4 and we're going to be py2 and I'm also going to change my font to bold so if we're a small button we just have less padding now for our gray classes these are going to be our color classes here we're going to check to see if we are currently gray if we are gray then we want all of our backgrounds to be gray so we're going to have a background gray of 400 our text here will be white and actually it'll be white no matter what so we can leave that off our hover for the background we'll change it to a slightly lighter gray and if the focus is visible for tab accessibility we're going to set it to the same gray 300. there we go now I want to set you to the exact same thing but I want to change these colors to Blue so we're going to here have a blue and this one's going to be a blue 500. this one is going to be a blue 400 and this one is going to be a blue 400 as well so depending on if we're gray or you know not gray we're going to have gray or blue Styles then on our button we can actually have our classes and the classes are going to be essentially all of our normal classes plus these custom ones that depend on all of our different styles so we want it to be round
Original Description
Try Out Amplication: https://amplication.com/?utm_source=wdsytc&utm_medium=cpm&utm_campaign=vid&utm_content=twitter_clone&utm_term=try_out_link_amp_hp
Amplication is open source. Star their GitHub repo: https://github.com/amplication/amplication
I finally created a project using T3 and I love the stack. tRPC, TypeScript, and Tailwind are some of my favorite tools. Being able to use them all on the same project in an easy to use way is so nice. This is the biggest project on my channel and I really hope you enjoy it.
📚 Materials/References:
GitHub Code: https://github.com/WebDevSimplified/twitter-clone
Prisma Crash Course Video: https://youtu.be/RebA5J-rlwg
Intl Formatter Video: https://youtu.be/4oGWpTAY_hc
🌎 Find Me Here:
My Blog: https://blog.webdevsimplified.com
My Courses: https://courses.webdevsimplified.com
Patreon: https://www.patreon.com/WebDevSimplified
Twitter: https://twitter.com/DevSimplified
Discord: https://discord.gg/7StTjnR
GitHub: https://github.com/WebDevSimplified
CodePen: https://codepen.io/WebDevSimplified
⏱️ Timestamps:
00:00:00 - Introduction
00:00:21 - Sponsor
00:01:38 - T3 Setup
00:03:40 - PlanetScale Setup
00:09:06 - Authentication Setup
00:12:05 - Deployment Setup
00:18:03 - Prisma Schema
00:23:00 - Sidebar JSX/Styles
00:31:45 - New Tweet Form JSX/Styles
00:49:13 - New Tweet Logic
00:55:05 - Recent Tweets Server Logic
01:07:18 - Recent Tweets JSX/Styles
01:29:22 - Like Tweet Logic
01:33:05 - Cache Update Logic
01:42:03 - Recent/Following Tabs JSX/Styles
01:52:27 - Profile Page Server Logic
02:05:42 - Profile Page JSX/Styles
02:16:35 - Follow Button Logic
02:22:22 - SSG Revalidation Logic
#T3 #WDS #NextJS
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Web Dev Simplified · Web Dev Simplified · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Introduction to Web Development || Setup || Part 1
Web Dev Simplified
Introduction to Web Development || Understanding the Web || Part 2
Web Dev Simplified
Introduction to HTML || Your First Web Page || Part 1
Web Dev Simplified
Introduction to HTML || Basic HTML Elements || Part 2
Web Dev Simplified
Introduction to HTML || Advanced HTML Elements || Part 3
Web Dev Simplified
Introduction to HTML || Links and Inputs || Part 4
Web Dev Simplified
Learn Git in 20 Minutes
Web Dev Simplified
5 Must Know Sites For Web Developers
Web Dev Simplified
10 Best Visual Studio Code Extensions
Web Dev Simplified
Learn CSS in 20 Minutes
Web Dev Simplified
How to Style a Modern Website (Part One)
Web Dev Simplified
How to Style a Modern Website (Part Two)
Web Dev Simplified
3D Flip Button Tutorial
Web Dev Simplified
How to Style a Modern Website (Part Three)
Web Dev Simplified
Animated Loading Spinner Tutorial
Web Dev Simplified
How to Write the Perfect Developer Resume
Web Dev Simplified
Animated Text Reveal Tutorial
Web Dev Simplified
Learn Flexbox in 15 Minutes
Web Dev Simplified
Custom Checkbox Tutorial
Web Dev Simplified
Start Contributing to Open Source (Hacktoberfest)
Web Dev Simplified
JavaScript Shopping Cart Tutorial for Beginners
Web Dev Simplified
Responsive Video Background Tutorial
Web Dev Simplified
1,000 Subscriber Giveaway
Web Dev Simplified
How To Prevent The Most Common Cross Site Scripting Attack
Web Dev Simplified
Transparent Login Form Tutorial
Web Dev Simplified
The Forgotten CSS Position
Web Dev Simplified
How to Code a Card Matching Game
Web Dev Simplified
10 Must Install Visual Studio Code Extensions
Web Dev Simplified
Learn CSS Grid in 20 Minutes
Web Dev Simplified
Learn JSON in 10 Minutes
Web Dev Simplified
10 Essential Keyboard Shortcuts For Programmers
Web Dev Simplified
What Is The Fastest Way To Load JavaScript
Web Dev Simplified
Differences Between Var, Let, and Const
Web Dev Simplified
How To Install MySQL (Server and Workbench)
Web Dev Simplified
Learn SQL In 60 Minutes
Web Dev Simplified
How To Solve SQL Problems
Web Dev Simplified
What Are Design Patterns?
Web Dev Simplified
Null Object Pattern - Design Patterns
Web Dev Simplified
Your First Node.js Web Server
Web Dev Simplified
How To Setup Payments With Node.js And Stripe
Web Dev Simplified
How To Learn Any New Programming Skill Fast
Web Dev Simplified
Asynchronous Vs Synchronous Programming
Web Dev Simplified
JavaScript ES6 Arrow Functions Tutorial
Web Dev Simplified
Are You Too Old To Learn Programming?
Web Dev Simplified
JavaScript Cookies vs Local Storage vs Session Storage
Web Dev Simplified
JavaScript Promises In 10 Minutes
Web Dev Simplified
Builder Pattern - Design Patterns
Web Dev Simplified
JavaScript == VS ===
Web Dev Simplified
JavaScript ES6 Modules
Web Dev Simplified
8 Must Know JavaScript Array Methods
Web Dev Simplified
CSS Variables Tutorial
Web Dev Simplified
JavaScript Async Await
Web Dev Simplified
How To Choose Your First Programming Language
Web Dev Simplified
Easiest Way To Work With Web Fonts
Web Dev Simplified
Singleton Pattern - Design Patterns
Web Dev Simplified
Responsive Navbar Tutorial
Web Dev Simplified
CSS Progress Bar Tutorial
Web Dev Simplified
Learn GraphQL In 40 Minutes
Web Dev Simplified
What is an API?
Web Dev Simplified
Learn How To Build A Website In 1 Hour!
Web Dev Simplified
More on: LLM Foundations
View skill →Related Reads
📰
📰
📰
📰
Tags, Releases, and Branches: A Practical Guide to Frontend Deployment
Medium · Programming
Tags, Releases, and Branches: A Practical Guide to Frontend Deployment
Medium · DevOps
Inside the Wayfair Frontend SDE-2 Interview: A Complete Breakdown
Medium · Programming
I Spent Two Years Maintaining a React SPA. HTMX Rebuilt It in a Week
Medium · Programming
Chapters (19)
Introduction
0:21
Sponsor
1:38
T3 Setup
3:40
PlanetScale Setup
9:06
Authentication Setup
12:05
Deployment Setup
18:03
Prisma Schema
23:00
Sidebar JSX/Styles
31:45
New Tweet Form JSX/Styles
49:13
New Tweet Logic
55:05
Recent Tweets Server Logic
1:07:18
Recent Tweets JSX/Styles
1:29:22
Like Tweet Logic
1:33:05
Cache Update Logic
1:42:03
Recent/Following Tabs JSX/Styles
1:52:27
Profile Page Server Logic
2:05:42
Profile Page JSX/Styles
2:16:35
Follow Button Logic
2:22:22
SSG Revalidation Logic
🎓
Tutor Explanation
DeepCamp AI