 I realized there's a set of steps that I do for any new project with a back end and a front end that I want to deploy on a publicly-facing website, and it's always difficult. Even for me, it's difficult to find, you know, modern steps to do it. Sometimes you can copy a boilerplate, and it's set up in a very specific way. I made my own boilerplate, it's at this repo, and it's based off this gist, which is a set of steps to do it from scratch versus cloning somebody else's repo, and I feel like that's the best way to really understand how to do something like this. And given that I think this is the most common thing that I do as a developer, I thought I'd record the process of doing it from scratch. So this is going to presume that you have a few basics, but not a ton, so the first thing that we're going to do is you'll have to have MPM installed and note. But if you have that installed on your machine, we're going to run this MPM command in a directory for our project. So I've got a folder on my Mac called podcast, that's going to be my project. Now I'll probably put some other files that don't need to go into the actual code repo inside this folder. So I always create another folder inside of that, and I'm just going to call it podcast because even though it's duplicative of the folder that preceded it, it will allow me to search for it. So if I were to just call it, I don't know, code or something like that, I might have a million of those if I develop more than one website on my hard drive. So calling it podcast, and then I use visual studio code, so I'm just going to drag that folder into my visual studio code thing in the app bar. So here we are inside that folder. There's nothing here. VS code has a terminal, so I'm going to open that terminal, but you could also use your Mac terminal or what is it, for Windows, power, I don't know, power, whatever, or I term, you can use whatever you want. I've got VS code, I recommend VS code, I recommend just setting it up so that you can use the terminal inside of VS code to run your terminal commands. Very first thing here is this terminal command, npm init y, so that just creates a package JSON file that allows us to install node packages, and it sort of bootstraps it with the defaults. So then I'm just going to keep moving through these steps here. So we're going to create a folder called server, and we're going to subsequently have a folder called client. So the server is the back end, the client is the front end. But inside the server folder, this is going to be a Node.js app, so we're going to create this index.js, and node just knows to look for index.js, just the same way that your browser knows to look for index.html as the default file. Okay, so I'm just going to copy this code, and run through it really quick. Express, require express, and express is a framework for the back end. So it's a way to run your server with some added sort of functionality. You could do this without express, but this is going to make it easier. And so we're going to establish a port, and the port is like where you would access this on your local host or where your server would serve up your back end. So it's going to look for your process.env.port specification, or it's just going to launch it on port 3001. So we probably won't bother with this. So when we run our server, it's going to launch it at port 3001. If you wanted to specify something different than this, you would create an environment variables file. So that's that process.env.port. So you would have to create a file called .env, and then you would say, in that file, port equals 999, or whatever. Save it as .env, but we're not going to do that for this. Okay, so then in my particular boilerplate, we just set up a route, which is the slash.api. And if somewhere we're to type into the browser localhost colon 3001 slash api, you would send back a response to the front end of our website, and it would say, you're connected to the server. So that's this message here. So it'd send that as JSON. And then the last piece is it's just going to listen for the port and say, okay, now we're listening on port 3001. So when the server is up and running, it's going to log this one time. So that's that first step. Okay, so you notice it's requiring express, so we need to install express. So I'm going to run that npm command. Okay, so what did that do? It installed express, and how do I know? I've got this dependency now, which is called express. So the other thing we want to do is package JSON has these scripts. And it comes with this test script. So if you ran npm run test, gives us this output, no test specified. Which is exactly what we see here. Now what we want is a start script. npm always looks for the start script to be able to just kick off your whole application. So I've got that start script here in the instructions. I'm just going to add that. So what that's going to do is when we say npm run start, or npm start, you don't have to say run, there's a shorthand. It's going to run this terminal command, node server slash index.js. Which is that file that we created here. So when we say npm run start, we can now run this. And so now, if I were to go to localhost 3001, that's our server. We can't get it because it's not a public route. So I'll clarify that later. But if we were to run localhost 3001 slash api, I have set up that route. And so it sent us this message back as JSON, and it says connected to server. So you'll notice that was our route that we set up here. Sent the message connected to server as JSON. Great, so that's how we use node and express and create a custom route. But that doesn't do much for us. So we need to create a front end that it will actually give us a little more of a custom typical website experience. So how are we going to do that? This is going to be a React app, which is kind of the most common front end stack for creating reactive websites. So I'm going to run, I'm going to stop that server. I'm going to run that command. Create React app client. So it's going to install all the dependencies of React in our client folder. So create React app is the NPM package, and client is the folder we want that installed to. And you'll notice when we run this, it's going to create its own package JSON file in client for the front end dependencies. So we already have one here in the root of our repo. But the client has its own dependencies, so it's going to have its own package JSON. Okay, it finished in the terminal. Create React app, created all kinds of dependencies and scripts and things like that to be able to run React. And we're not going to worry about explaining that right now. But we have a front end, essentially. But we need to be able to allow the front end to talk to the back end. So that's where this comes in. In that client package JSON, we're going to add this line. So just down here at the bottom, proxy localhost 3001. Now, if you remember what 3001 was, that is the port in which our server is running. So we're in the root of our repo and say npm run start. That starts our server. If I run another terminal window, and I change to the client, the front end, and I also say npm run start, that's going to start our react app. It's going to open up a window by default. That's something that this create react app gives us. And we see a front end of a website with some boilerplate UI. It's something to see on screen. Obviously, we don't want that. We're going to get rid of it. But now we've got a front end and a back end running. Okay, so I mentioned we were going to get rid of all that code on our front end. So I'm going to go into source app.js. This is react code here. And if you want to verify that what we just saw is what is being served on the front end of our app, you can see it here. We've got this paragraph tag, edit app.js to save and reload. That's this. And we've got this spinning react app logo, that's that. Learn react, et cetera. Okay, so we don't want that. I'm copying and pasting from this gist, the front end that we want to see right now. So I save that. Now, this automatically refresh the page that something create react app does. It watches for changes and it refreshes the front end. And so what we see on screen now is connected to server. Why do we see that? Because of this right here. If you know react and you should learn it. But there are these things called hooks and the most basic hook I would say is called use effect. And that is designed to listen to whatever you specify in this array here. So it's going to listen for changes to certain things and then it's going to do whatever you tell it to do. So this is a function call. That's just an anonymous function in this case. It's going to say, okay, whenever there's a change to anything because this array is blank, it's going to like if there's any change that happens in the react app, it's going to go fetch our API right route from the back end. And then it's going to take a JSON response. It's expecting JSON. And it's going to surface that as a variable called data. And then it's going to run this state action called set data. So it's going to save the data.message to state. And then, so okay, it's in state, but how do we see it? Well, if you know react, you know whatever it puts inside this return statement is what you see on screen. So what you're going to see on screen in this case is just a div called app with a header called app. And a paragraph tag that says, if we have data in state, show this status message, loading data, sorry, loading, or if we have data, show the data. So in this case, we do have the data from our back end. So it says connected to server. So how do we know the data from the back end? Well, we called that fetch route, fetch API. API said, okay, I heard somebody calling my name. I'm going to respond with the fact that you are indeed connected to the server. The simplest way we can wire the front end to the back end. So there you go, you got a front end and back end of a react app, react node express app talking to each other. What's next? Okay, we don't need two git files on top of each other. We just need the one in our route. So we want to make sure that any changes we make to either the front or the back end of the app are saved in git, but having a git repo inside a git repo is not something we want. So I'm going to have to show the invisible files here in Mac. It doesn't show those by default. So I just entered a shortcut to show invisible files but you could do view, I don't remember where it is. Show view options maybe, I don't know. You're gonna have to look at what the shortcut is a shift command period, but there's some other menu option that will allow you to show the invisible files up here, not big on shortcuts. But anyway, because it's a folder that starts with dot, Mac hides these by default. I'm not sure what PC does, but it's got its own git repo in here and we're just going to delete that. You could also type in these terminal commands here, but I'm just gonna do it through a graphical user interface because I'm a visual person. All right, and then now I'm providing some modified code to put on the back end. We're just gonna paste that in there. So this is existing code, this stuff up here, but I'm gonna paste in these changes. Sorry, that could be a lot clearer, I think. I will change that documentation, but really what you should be doing is pasting right here. So what we're doing is we're saying, serve the files for our React app out of this client build folder. And you'll notice we have client, we don't have a build folder yet. And I will cover that in a minute. We wanna actually build our app at some point so it will serve up sort of like a bundled up version of our front end. Right now what we have is source folder. We don't have a build folder. So the source contains all of our source code, but we don't want the average person to be able to see all that stuff. We wanna deliver them an optimized and secure and private version of the website that doesn't compromise any secrets or anything we don't want them to see that will load faster, et cetera. So that's gonna be in that build folder. That's why this says serve up client dot build. So why is it dot, dot, dot? Cause our back end is where? Within server, but if we're operating within server, we wanna go back a directory, the dot, dot slash, which puts us in our root and then into the client folder and then into a build folder, which we will create shortly. Okay, so that's how we wire up our front end. We still have this thing where if we fetch the API route, it'll respond with connected to server. And then what express does is it says, for anything else that doesn't match anything above it, and in this case, only API, we're just gonna say serve up the index dot html file out of the build folder. So when you don't know what to do, just serve up the root file out of the front end. So I'm gonna save that. And now we need that build step. So we're gonna add to our, sorry, I can't type package JSON in the root. Have that start step. Let's add the build step and what is that step? It says change to the client directory and install any dependencies that we need for React and then run the build step. So I'm gonna save that. And then the other thing that we wanna do, and this is gonna be for servers or like Heroku. In this case, we're gonna use Heroku. We wanna add this engines declaration. And the reason we want that is it's just gonna tell us what version of node to run. Well, how do we know what version of node we have? Say node v. We could put whatever we want here. In fact, we may wanna do something that's backwards compatible. We don't necessarily need node version 18, but since I'm gonna be doing some kind of cutting edge code in this app, I'm gonna just use node version 18. So where it says your node version, we'll just say greater than or equal to 18.0.0. Hopefully that should get us there. I think that should be fine. I don't know. Now we need a get ignore file that's just gonna ignore all the stuff that we don't want to commit to our repo, just in case we wanna do this as open source or whatever, whoever has access to this repo, we don't need them to install all this unnecessary stuff that may accumulate on our computer as we build this app. So these are some common things that are encompassed in that and they go into a get ignore file. So I'm just gonna say in the root of our repo, I'm gonna create a new file, I'm gonna save it as dot get ignore. Ignore that warning. Let's just tell me that dot files are often hidden. That's what we want. So it's gonna say, okay, ignore anything in node modules. Why that? That's where anything we install with NPM install goes. So you can see for this app, we've got all kinds of folders here with files inside of them and that's the stuff that node and express need to run. So it's got a lot of dependencies but we don't wanna commit those because that just takes up space in our GitHub repo and it doesn't really relate to the code we're writing. It's just part of that NPM package and whoever you distribute this code to, they can get all that stuff when they run NPM install. So you don't need to host it up on your GitHub repo because that would be excessive. So we're gonna ignore node modules. We're gonna ignore that dot env file which if you remember, that's where we're gonna put all our secrets. And then this DS store is a Mac thing but PC has I think something similar or maybe the same thing. Which just like is a way to index what's on your computer file system. And so anyway, it creates these dot DS store files that I think serve some metadata about your file system. That makes it easy for finder in this case to find your files and know when they changed or whatever. So anyway, those are just common things to put in your GitHub ignore. All right, so we've got that. Now we're ready to put this thing somewhere where people can see it. So I've already done this step. So it wouldn't do anything if I do it. But what we want is the, if we're gonna put it on Heroku, we want the Heroku command line interface. You might see the acronym CLI. That's what that stands for. It's just a way for services to be able to give you a set of commands that you can run on your terminal, on your computer that allow you to interface with their service. So I could say, oops, where's my password? I could run this command. Doesn't hurt. It will update anything that has changed. But it's just installing all these dependencies and this slash g means we're installing them globally for anybody, anywhere who wants to run these Heroku commands. It's gonna take some time. And we're getting these errors because it already exists. So no problem. You probably won't see those. I've got the command line interface. Hopefully you do too. Because now you can run this next command which is Heroku login. It says hit any key. I'm gonna do that. It's gonna open a web browser. You're gonna have to create an account. I've already created an account and since I've logged in recently, I was able to just hit that button and it said okay, you're logged in. So when we go back here, you see these messages logging in, done. You're logged in as your username. Awesome. Now, what Heroku needs is a publicly, well, it needs a GitHub repo. So let's create one. Repositories, new. If you have multiple GitHub accounts, you'll need to specify which one you're adding it to. So this is mine. Podcast, ask questions about podcasts episodes. And receive answers from an AI chat bot. That's what my app is gonna do. Make it public. You don't need to read me file yet. We've already created a Get Ignore file so keep that. And I'm not gonna specify a license right now. Okay, so that repo is created. This is the URL and we can refer back to it later. But now we can run the set of commands to add to that repo. So get init just says, okay, create a Get repo at the root of our folder here. And you wanna make sure that you're actually in the root of the folder when you run this terminal command. How would you know? You can type PWD, which is present working directory. And it's gonna say, okay, I'm in this directory on my hard drive. If I wanted to click on that, let's see, what's the command? Open, that opens my finder and we can see, okay, yep, I've got my client, my server, my package JSON. So I know I'm in the root. I run this command. Okay, all right, so if we wanna see what we're about to commit to the repo, say, get status. And it's telling us all the stuff that is in here, but it's saying nothing's been added. But this is what it wants to add. And I'm actually seeing this node modules folder, which we put in our get ignore. So there's a problem there. We don't want that and I can see what it is. Got this comma in there. So it's not gonna match that pattern because it's not finding it. So let me make that change and I need to change that in my instructions too. But anyway, now the node modules are gone. So that's good, we want that. We actually, yep, no, everything's good now. So now we can proceed with these instructions. Get, add all of this stuff. And if we type get status now, it's gonna say, okay, this is all the stuff that is ready to go into get. And there's no node modules, but there is all this client code, our package.json, our server index file, et cetera, as well as a get ignore file itself. Okay, so now how do we push it up to our GitHub repo or how do we commit it to get? We say get commit and we just give it a message and that message is, this is our first commit. Now, the other thing that we do here is we just want our remote server to have a branch called main and we're gonna tie that repo that we created to our local repo. So it's gonna say, okay, when we push the code from our local repo up to GitHub, this is where it's gonna go. So paste this code, whoops, okay, there's that code. And then rather than all this stuff here, just get remote, add origin and then whatever the URL of your GitHub repo is. There we go. So now it's got a place to go online and now how do we push it up to that repo? So get push, we wanna make sure we're authenticated and then our origin is the nickname for like the main place where we're putting it, which is GitHub. We could put this on Bitbucket or some other place and then what branch are we pushing? We're pushing the main branch. So that's kind of the default place. We do that, it writes it and now if we go here and refresh the page or see that all of our code is up on GitHub, okay? So we want it to get onto Heroku onto a server that can actually like run this app. So we can run it locally, but we can't, no one else can see it, right? Like nobody's gonna see local hosts, that's for us. So we're gonna use that Heroku command line interface to add a remote for Heroku. The same way we added one for GitHub. So we're gonna say Heroku, get remote, add and then we just give it a name, I call it pod quest. So now if I were to say get push Heroku pod quest, it would know where to push this code and then I'm just gonna add a commit message there. Okay, so now if we wanna put it up on Heroku where we do, get push Heroku main. So instead of origin, we now have Heroku. So instead of going to GitHub, it's going to Heroku and web branch, the main branch. So it's gonna take some time and if we want, we can check to make sure it's working. I'm logged in, I use Mozilla as my default browser so I'm logged in there and our app was called pod quest. If we look at the activity, it's building and we can actually see all the things that it's doing and that's the same stuff we would do on our local computer but it's doing it on the Heroku servers. So it's installing the binaries from package JSON so all of our NPM dependencies running the build, NPM run build, it's doing all this stuff and so we should, oh, but we're not up and running. We have an error. This is good, this will help you understand how to troubleshoot an error. So it gives us a command to run to figure out what happened on Heroku. So Heroku logs, so we're looking at the server logs and we scroll to the top of the server log, says okay, we created a release. The build succeeded, so it actually built the app and then we tried to start it and that's where the error happened and if you look at these closely, this will take some work to figure out where your error happened but it's saying reference error path is not defined and where did that error occur? It occurred in our index.js file in our app server folder at line eight, column 24. So that tells us exactly where to look for the error and if I look in index.js, this is line eight and column 24 just means like how far over in the text. This is column 24, we see this referenced path. So it's saying, it doesn't know what path is, there's no variable here called path. We required express, but we didn't require path. I'm using GitHub Copilot and it's saying yo, put that in there. So I'm just gonna accept that but that is how you require the path. So I missed that my bad, and I also have to change the instructions to specify that. So now we need to, we made that change. Sorry, so we need to add it, specify path dependency. I can commit it to GitHub and I can commit it to Heroku. Again, it's gonna go through this process. You can watch it as it happens. It's running the build step. Okay, it says build succeeded, which happened last time, maybe we still got an error. So we need to wait and make sure this actually worked. And this is where it's telling us it's gonna find our app. We've got it open, we still have an error. See what it says, app crashed. So it didn't find our root path here. So something must be missing. Let's go back to our tutorial here and see what it asked us to put in. We've got that stuff, did it delete something that? Oh, yes, of course. Yeah, I did. When I pasted in this updated code on the server, I deleted something I shouldn't have, which is the thing that tells Node to listen to the port in the first place. So I'm gonna add that in. I'm gonna commit it to git, the message, add the port, listen, git push, Heroku, push our main branch, gonna kick that off. While it's doing that, I will push it also to GitHub, which we called origin, that's done. All right, let's hope this works. You can see the field is in progress. Check our status, did it, open our app, and hopefully, yay, we got it. Okay, so now whatever we ran on our local host, you can also now see on Heroku. So that's it, 40 minutes in, we have a full stack Node Express React app doing absolutely nothing. But that is modern web dev. That's what it takes to deploy a full stack app to a hosted cloud service. And in future tutorials, we can talk about how to make it actually do something more interesting than, say, connect it to server.