This isn’t a horrible approach while debugging a JS application.
In the constant pursuit of learning and improving myself, I’ve discovered that going through books is a great way to expand my knowledge on a wide variety of subjects. I’m going to keep this post open and update it with each new book I read.
I’ve categorized the book list into the following divisions:
- Faith & Spirituality
- Development & Science
2020 Book List
Book List Category: Faith & Spirituality
- Different Kind of Happiness
- Own The Moment
- Bridge to Haven
- Amazing Truths: How Science and the Bible Agree
- The Scarlet Thread
- Double Blessing: How to Get It. How to Give It.
- The Warrior: Caleb: Sons of Encouragement
Book List Category: Business
- Way of the Wolf: Straight Line Selling: Master the Art of Persuasion, Influence, and Success
- The Go-Giver, Expanded Edition: A Little Story About a Powerful Business Idea
- The Score Takes Care of Itself: My Philosophy of Leadership
- The 1-Page Marketing Plan: Get New Customers, Make More Money, And Stand Out From The Crowd
Book List Category: Development and Science
- Understanding Complexity
- The Intention Experiment: Using Your Thoughts to Change Your Life and the World
- Into the Magic Shop: A Neurosurgeon’s Quest to Discover the Mysteries of the Brain and the Secrets of the Heart
Book List Category: Skill
- Linchpin: Are You Indispensable?
- Abundance: The Future Is Better Than You Think (Exponential Technology Series)
- The Worry Trick: How Your Brain Tricks You into Expecting the Worst and What You Can Do About It
- Think Like Sherlock: Creatively Solve Problems, Think with Clarity, Make Insightful Observations & Deductions, and Develop Quick & Accurate Instincts
- Indistractable: How to Control Your Attention and Choose Your Life
- Ultralearning: Master Hard Skills, Outsmart the Competition, and Accelerate Your Career
- The Elephant in the Brain: Hidden Motives in Everyday Life
- Solve for Happy: Engineer Your Path to Joy
- How to Consciously Design Your Ideal Future
Book List Category: History
- Ancient Civilizations of North America
- The Medieval World
- Break Shot: My First 21 Years
- What Do You Care What Other People Think?: Further Adventures of a Curious Character
- The World of Lore: Dreadful Places
Book List Category: Fiction
Hi, and welcome to this course where we are going to learn how we can create a Rails API application that uses authentication and works with a React JS app. So the use case for this is if you want to built out your own authentication from scratch, especially if you’re building out authentication for a front end application. So if you want to add a registration and a sign in component to react or to angular or Vue JS, then this will walk through exactly how to do that.
Now we are going to be implementing HTTP only cookie authentication. There are two popular types of authentication. One is to use HTTP only cookies. The other is to use what are called JWT tokens. Now I prefer to use HTTP only cookies, mainly because it leads to a much more straight forward interface.
With JWT tokens, you generate these randomized encrypted tokens and then both sides of the application have to do quite a bit of work to one, make sure that the tokens are still accurate and that they’re still matching, that they haven’t been hijacked and the front end application has to store it in local storage or something like that.
And then the back end constantly has to check that, and it feels like that’s not really the best fit, especially if you’re a rails developer. With rails, you have the ability to utilize the session and so what the session does, if you’re familiar with MVC applications, you can store anything you want in a session, such as if a user’s logged in or not, and what we can do with an API can actually take advantage of this same exact set of features. So we can use the session the same way we would with a traditional MVC app, even though it’s an API.
So we’re gonna walk through all of the steps needed in order to do that. In this guide, we’re going to generate a Rails API application from scratch, and we’re going to add the dependencies needed for building our own authentication. From there we’re going to configure the app to work.
So let’s get started.
I’m going to create a new application here, running the command:
rails new authentication_app --database=postgresql
Now you may notice I did not use the API only flag. Rails does have the ability to create a API only application, however, if you do that, you actually won’t be able to use the session properly.
So I’m generating a regular application, just like a standard MVC app, but we’re not going to use any of the views, we’re going to treat it like an API only application.
So now that that’s been generated, let me jump into the authentication app and I’m gonna start up team ux here.
First, we need to create the database, by running:
And then after that, we’re going to add two gems to the
gem 'bcrypt', '~> 3.1', '>= 3.1.12' gem "rack-cors", :require => 'rack/cors'
And then run
bundle install to install the dependencies. With that in place, we can start building out our configuration.
We are going to start by adding a couple files, starting with the
Create a file:
config/initializers/cors.rb and add the following content:
Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins "http://localhost:3000" resource "*", headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head], credentials: true end allow do origins "https://your-production-app-here.com" resource "*", headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head], credentials: true end end
So what is the purpose of this cors file? Cors gives you the ability to white list certain domains because we’re going to be passing secure cookies back and forth between the front end application and the back end application. And we need to be able to use a tool called credentials, and so what’s required with Rails is that if you’re gonna use credentials, which means that you’re gonna work with the session, then you have to implement a tool like cors and give a specific set of rules for how you are going to be able to communicate. And these rules are defined in this initializer.
Let’s walk through what this code is doing. We start by inserting a level of middleware here and we’re using the cors module to do it. So all of the rules that we place inside this code block are going to be intercepted by the rails config so we’re saying at the very top of the chain, we want to establish these rules. Because if a application tries to communicate with our system that’s not authorized to do so, and they’re coming from a domain that we have not white listed, we don’t want to give them any access to the system.
From that point, we create an
allow block, and then give an origin. The origin is a string and is a list of domains that we want to whitelist. For this application we’re whitelisting localhost for local development for our front end application, and then the domain for where the front end application will be deployed.
Make sure you note that with the localhost code, the port is going to change depending on what kind of front end application you’re working with, and what port you’re using. For example, if you’re using Vue JS, then you’re probably going to use localhost 8080, or if you’re using some specific type of react application that runs on a different port by default, you’re gonna use whatever port it runs on.
After that, we have to list off the resources, headers, and HTTP methods that are allowed. We are going to allow all of the resources our whitelisted domains. This means that the domains that we whitelist will have the ability to create, update, delete, etc.
Lastly, we’re adding the
credentials: true flag at the end of the line. This is what is going to allow you to pass the HTTP only cookies back and forth between the front end and backend applications. If you do not put that there, it will not work.
After that, create a
config/initializers/session_store.rb file and add the following content:
Rails.application.config.session_store :cookie_store, key: "_authentication_app", domain: "your-production-app-here.com"
The session store is where we define what the cookie’s going to be structured like. So with session store, we’re saying:
- We’re going to use the Rails’
cookie_storesystem to manage our sessions.
- The name of the cookie will be:
- The domain will be
Obviously you’ll need to pass in your own domain in that section.
With that completed, we’re ready to start building out the registration and login features into the Ruby on Rails API.
In the constant pursuit of learning and improving myself, I’ve discovered that going through books is a great way to expand my knowledge on a wide variety of subjects. I’m going to keep this post open and update it with each new book I read.
I’ve categorized the book list into the following divisions:
- Faith & Spirituality
- Development & Science
2019 Book List
Book List Category: Faith & Spirituality
- Joseph: A Man of Integrity and Forgiveness (Great Lives From God’s Word)
- Think, Act, Be Like Jesus: Becoming a New Person in Christ
- Hope in the Dark: Believing God Is Good When Life Is Not
- Everybody, Always: Becoming Love in a World Full of Setbacks and Difficult People
Book List Category: Business
- Total Focus: Make Better Decisions Under Pressure
- Buffett: The Making of an American Capitalist
- Psyched Up: How the Science of Mental Preparation Can Help You Succeed
- What Every Body Is Saying: An Ex-FBI Agent’s Guide to Speed-Reading People
- Great at Work: How Top Performers Work Less and Achieve More
- Made to Stick: Why Some Ideas Survive and Others Die
- The Innovator’s Dilemma: The Revolutionary Book That Will Change the Way You Do Business
Book List Category: Development & Science
- Writing Your Dissertation in Fifteen Minutes a Day: A Guide to Starting, Revising, and Finishing Your Doctoral Thesis
- Clean Architecture: A Craftsman’s Guide to Software Structure and Design
Book List Category: Skill
- Can’t Hurt Me: Master Your Mind and Defy the Odds
- Own the Day, Own Your Life: Optimized Practices for Waking, Working, Learning, Eating, Training, Playing, Sleeping, and Sex
- Your Brain at Work: Strategies for Overcoming Distraction, Regaining Focus, and Working Smarter All Day Long
- Willpower Doesn’t Work: Discover the Hidden Keys to Success
- The Bullet Journal Method: Track the Past, Order the Present, Design the Future
- The Power of When: Discover Your Chronotype–and the Best Time to Eat Lunch, Ask for a Raise, Have Sex, Write a Novel, Take Your Meds, and More
- Perennial Seller: The Art of Making and Marketing Work that Lasts
- Practice Perfect: 42 Rules for Getting Better at Getting Better
- 13 Things Mentally Strong People Don’t Do: Take Back Your Power, Embrace Change, Face Your Fears, and Train Your Brain for Happiness and Success
- The 1% Rule: How to Fall in Love with the Process and Achieve Your Wildest Dreams
- Digital Minimalism: Choosing a Focused Life in a Noisy World
- Stop Doing That Sh*t: End Self-Sabotage and Demand Your Life Back
- How to Consciously Design Your Ideal Future
- Everything Is F*cked: A Book About Hope
- Atomic Habits: An Easy & Proven Way to Build Good Habits & Break Bad Ones
- Barking Up the Wrong Tree: The Surprising Science Behind Why Everything You Know About Success Is (Mostly) Wrong
- Better: A Surgeon’s Notes on Performance
- The Tao of Pooh
- Stealing Fire: How Silicon Valley, the Navy SEALs, and Maverick Scientists Are Revolutionizing the Way We Live and Work
- Hyperfocus: How to Be More Productive in a World of Distraction
- The Captain Class: The Hidden Force That Creates the World’s Greatest Teams
- Solve for Happy: Engineer Your Path to Joy
- If I Understood You, Would I Have This Look on My Face?: My Adventures in the Art and Science of Relating and Communicating
Book List Category: History
- Benjamin Franklin: An American Life
- Twain’s Feast
- The Ranger Way: Living the Code On and Off the Battlefield
- Brave Companions: Portraits In History
- The Dictator’s Handbook: Why Bad Behavior is Almost Always Good Politics
- Springfield Confidential: Jokes, Secrets, and Outright Lies from a Lifetime Writing for The Simpsons
- Rivals! Frenemies Who Changed the World
Book List Category: Fiction
In this Vue.js tutorial, we are gonna take a deep dive and look at the lifecycle hooks provided from the Vue framework.
Now, we’re going to analyze the lifecycle diagram, and then go and implement this into a Vue application. We’re also going to extend it, because this lifecycle set of hooks and what they list in the documentation is helpful for understanding, because it’s a helpful visual. But I think that it’s missing a couple of elements that I personally have had to implement into my own production Vue applications, and so I think it will help for you to see those as well. So we’re gonna walk through quite a bit of material in this guide.
So I have a Vue application running right here in the background, and we’re going to be looking primarily just at a few different components. So we’re going to be looking at a dashboard component, a Vue component right here, and then that has the nested login component.
And so what we’re gonna be doing isn’t as much building in this guide, we’re instead gonna be looking and analyzing to see how exactly the lifecycle process works.
If you are not aware of this, if you’ve never heard of the lifecycle, or if you’re just trying to understand it for the first time, the best analogy that helped me is trying to compare a Vue component to us humans.
So as a human, we are born, we go through different stages in life, and then, even though it may seem dark, we all die at some point. Well, that’s the way a Vue component works too. A Vue component is born. We say that a Vue component is created, then it has a number of things happen. It has changes go on, such as data changes, and updates, and those kinds of. And then at a certain time, it also dies, or we say that it is destroyed.
So what we can do with Vue is we can actually listen for and capture those events, each one of those, from created all the way through destroyed, and then update the application based on the state of the component.
So hopefully that starts to make sense. But what really help understand the lifecycle hooks and the entire process was really just getting in and implementing each one of the methods.
I’ll provide in the show notes a link to this documentation, ’cause that can help to have a visual. But I think what helps the most is just going in and writing the code.
So I’m going to switch back to our application here, and then opening up Visual Studio code here, you can see that we have our homepage component, which is just rendering out some content, and then our login component. And that’s pretty much it. That’s pretty basic right now.
So we’re gonna start in the dashboard, and I’m gonna go out, and I’m gonna start listing some of these hooks. Now, right now we have a pretty basic setup where we have our data function, then we have a list of the components that we are registering, and then we have one custom method. I usually by convention place these lifecycle hooks right above the methods, I like to have my methods at the very bottom, so I know exactly where they’re at. But you could technically put these anywhere inside of the script tag, as long as it’s right after the default curly braces.
Now, I’m going to just list off a couple basic ones here first. So I’m gonna say beforeCreate(), and it is a regular method, so you have to have the parens right after it. And then I’m going to console.log and then say beforeCreate, just so we know exactly what’s happening here. And then for this one, I’m also gonna say this afterwards, ’cause this can be really helpful in understanding what we’re referencing. And then make sure you put a comma there. And then after that say created.
Now, unlike some other methods or names inside of Vue, these are reserved words. So before create is something provided by Vue directly. Created is something provided by Vue. So these are reserved and they are names and functions that are built directly into the Vue source code.
I’m going to copy this console log here, and then change this to say created. And I’m not gonna pass in this or else it’ll make the output a little bit messy, and you’ll notice that the this that it’s referencing is gonna be the same for all these elements.
So let’s just start with these two, and then we’ll get into some of the other ones after this. So switching back to the browser, I’m going to clear the output, hit refresh, and now you can see that we have some console log statements here. We have before create, and then created. So both of these worked. So they were triggered. Notice that we didn’t do anything. All we did was we listed them out inside of the component.
Now, when I used the this call, so when I said beforeCreate and then passed in this, all this is doing is giving a reference to this component, meaning the dashboard component. And the way we can know that is this is an object. And so if I click on here, I can see everything inside of it, everything that has reference too. So you can see it has a list of attributes. So if I click on attributes, you can see it’s an object, and then inside of here all kinds of different object values.
Then this one is the one I think is pretty neat and very helpful is children. You can that our dashboard component does have two children. You can even just go and reference them here. We have a homepage content component, and then a login component. And that is what this is referencing here. And then it has a element so that we know that it’s a diversity. You can hover over it, and you can see what the element entails, it can have listeners, you can have a list and a reference to its parent.
So that is kind of a helpful way of understanding what this is. I want this guide to specifically focus on the lifecycle components, but I just put that in there just so you can see that you have a reference, you have a direct reference to this inside of each one of these lifecycle hooks.
So you saw that these were already triggered. Let’s move down. I’m also gonna get rid of this and clear it out, just so we have some nice clean output.
Now I’m gonna go and I’m gonna list all the rest of the lifecycle methods that we have access to. So the next one’s gonna be mounted. And then the one after mounted … or actually, you know what, I forgot one. There is one right before it called beforeMount. And so we have access to beforeMount here, then mounted.
And then from there we have our update methods. So this one is going to be beforeUpdate. And there’s gonna be something a little bit tricky with the update method that I’m gonna show you here in a second. Then the next one is updated.
So we have updated, and then we just have two more. So we’re going to have our beforeDestroy, and then we’re gonna have after that one our destroy, beforeDestroy, and then destroyed.
I do like the naming that they went with here. If anyone has ever been through my tutorial for the React lifecycle hooks, React went with a little bit more challenging of a naming process, and it makes it a little bit harder to remember all of them. But Vue, I really like the names that they went with, because you can pretty much, as long as you can remember half of them, that means you have remembered all of them. You have beforeCreate, created, beforeMounted, mounted, beforeUpdate, updated, beforeDestroy, and then destroy. That’s a very kind of a common approach to being able to name them. So you just have to memorize about four items, and then you’ll know all of them.
So now that we have that, let’s go and switch back to the browser here. And I’m going to refresh, and let’s see when each one of these is triggered. So right now, we have beforeCreate, created, beforeMount, and mounted. So we before we did anything, notice we didn’t do anything on this page, nothing happened, all we did was we hit refresh, then the page loaded, and four items here were triggered.
Now, let’s take a look at that lifecycle visual once again, ’cause it helps to kinda see all of the items that took place during that process. It may not seem like anything happened, but as you can tell, a lot of things were happening in the background.
So when the lifecycle diagram says new Vue, this means that a new component is being instantiated. So it’s going to run the intializer, which means it’s gonna be … intializer, it’s gonna be created, and then it’s gonna set up all of its data, and all of its dependencies, everything like that is being brought in, before create and created are gonna manage those processes. So if you need access to something very early on in the component lifecycle, then these are gonna be the lifecycle hooks that you would use.
Then the created method then is going to take it from there. It’s going to take it, it’s going to see, does it have an element option. If no, then it’s going to perform one process, if yes, then it’s gonna see does it have a template option.
So these items are really related directly to the data that’s being rendered out onto the screen. It’s checking to see what kind of values that it’s gonna be presenting, if it is gonna presenting them to the user.
Moving down, you can see from there it’s gonna check to see does it compile the template into a render function. If yes, it’s gonna come this, or if it has a template option, then it’s going to then say compile the elements outer HTML as a template.
Now, if some of this is confusing, don’t worry. It’s very confusing especially if you’re new to Vue. I more just wanna kinda show you that as you are building your Vue applications out, you’re gonna noticing a lot of things are happening behind the scenes. And sometimes that can be a little bit confusing or intimidating. I wanna show you that there’s actually just a set of processes that Vue is going through. It’s almost like a set of checkboxes, and it’s saying, “Okay, I need to know what this component is trying to do. Is it trying to show the user something? Is it just a small presentation component, or does it have all kinds of data? And do I need to run all these processes?” So that’s really what this lifecycle is about. It’s Vue trying to figure out what it needs to do.
And then from that process, it goes into the beforeMount process, and then it creates the element, and it does all kinds of different Vue-related items, and then comes down into mounted.
Now, one thing I will tell you from experience. I built out multiple production applications in Vue, and I will tell you that I probably spend when it comes to these lifecycle hooks, I probably spend about 90% of my time using just two or three of them. And so I’m really gonna focus on those, and I’ll let you know which ones they are.
The mounted hook is most likely the one I use the very most, because this means that Vue is already figured out what kinda component it’s dealing with, it has initialized all of the different elements that it needs from a template perspective from the div element, it’s set up its own version of the DOM on the page, everything like that, and it’s mounted.
So this is where I do a lot of the set up for my components is in this hook right here. Now, once it is mounted, that means that it is loaded up on the screen. You can see if you come back here that mounted was the very final step in the process when the page loaded. And then from there, once it is loaded, now we get into what happens when something gets updated on the screen. Remember, one of the top reasons why you use frameworks like Vue, or Angular, or React is because you want your application to be dynamic. You want the ability for a user to click buttons, and type into forms, and to have other actions, and other behavior to be automatically triggered inside of that application. And so what goes on at this stage of the process is very critical. And you may have noticed that our beforeUpdate and our update did not get triggered.
Now, I wanna show you something a little bit interesting. This may be a little bit odd to you, but you know that we have a login form right here. And just to review what that looks like, we are calling a login component, so recalling an external component, and then we have this update listener inside of the login component. Well, you would think that would mean that when the data gets updated in login, it’s going to update our dashboard. But let’s see exactly what happens.
So if I type an email in here and click on login, you can see that it did console-log some data out, that is all that’s happening inside of this update login details. We’re omitting an update event, and we’re passing in the email. And that’s all we’re doing. But notice that our beforeUpdate and our updated lifecycle hooks were not triggered. And that is because we didn’t actually update anything inside of our dashboard component. Everything was encapsulated inside of the login.
Now, if I were to take these, so I’m gonna copy these functions here, and I’ll place me inside of the login component. Now, if I do this, and let’s just be clear here that we’ll say beforeUpdate from login, and then updated from login. If I hit save now and come back here and start typing, even as I’m typing, before I even submit the form, it is updating. We have the beforeUpdate and we have the updated, and both are only in the login, we’re still not making any changes directly in the component.
So this is something that can be very confusing, if you’ve never seen it before, because you may think that a parent’s components if it has any child component updates, you would think that it receives all of those. But Vue is very good at isolating those update events. So if you wanna capture something in the update stage, you need to make sure that you are doing that in the component itself.
So let’s stretch that, just so you believe. Let’s go into the dashboard, and I’m going to add one more little form element here. So I’m gonna say input text and we’ll connect this. So I’ll say bind it directly to the dashboard data model. So say v-model and we’ll just say something like maybe subdomain. It could be anything. It could be ASDF or ASTF, it doesn’t matter you can call this whatever you want. And then add in a subdomain data element here, so we have something that it can bind to, hit save. And now you can see we have this new form field. I’m gonna close this, and if I start typing anything, you can see that now that beforeUpdate and the updated lifecycle hooks were triggered. So that is one of the biggest take aways I want you to have from this entire guide, is understanding the way the update cycle works, because that’s something that you’re going to wanna tap into as you’re building out the applications, and understanding that it’s encapsulated inside of the component that’s being updated is very critical.So that is how the how the update process works.
And now we have two more, and I’m going to describe what they do, and then I’m gonna explain what their role should be, and then I’m gonna show you two more that weren’t listed. And these other two are ones that aren’t technically lifecycle hooks, but I think they should be seen in the same light, because they are used with the same type of intention, and hopefully that’ll make sense when I walk through it.
So what beforeDestroy and destroyed do is they are watching for when the component is removed, when it’s taken off of the stake. So let’s say that we have all of our data here, and then a user goes and clicks on home. Now, they’re redirected to the home component, and what happens, you can see right here, is our dashboard component has been destroyed, and it is no longer there. So the main role of what it is going on here with this lifecycle hook is that this gives you the ability to be able to clear off any processes.
So a very common thing that I use this for is say that you have an application and one of the component so has a timer in it. So I built a invoicing application that had a timer on one of the pages where you could record your time as you’re working. And that timer was running anytime that component was alive. Well, when the user left that page, the timer needed to stop or else the timer would keep on running in the background. So the destroyed hook allowed me to do that. I was able to say, “Okay, we are going to destroy that timer. We’re going to stop it from running that way we don’t have any memory leaks.” That’s really what the destroyed hooks are for, is for being able to clear out any processes the you do not want to keep running.
So let’s go back to the dashboard, and we’re gonna go through two more methods. And these are not listed inside of these lifecycle hooks, because technically they are route watchers. And when … I mean route watcher, I mean they’re watching for changes in the route by the user which that is technically not associated with the lifecycle hook, but it is associated with the way a user’s interacting with the component, and that’s the reason why I wanted to include it in this deep dive.
So now what I’m going to do is I am going to come down here under destroyed, and I’m gonna add a new hook. So this is gonna say beforeRouteEnter, and then this takes three arguments, to, from, and next. Now, inside of here … So what this is doing, and then also make sure you’re giving a comma here at the very end.
So what beforeRouteEnter does is it listens for when a user is trying to access this route. So the most common time that you’re gonna use this is to check to see … So say that you have a part of your application that you only want a authorized user to access. That’s a very common use case. Well, this allows you to do that.
So let’s say that we are connected to an authorization API, and I say const loggedIn, and for right now we’re just gonna assume they logged in successfully, the API said, “Yes, this user is authorized so we’re gonna say it’s true.”
But if they’re not logged in, then we want another process to take place. So here I can say next, and then as a string, pass in the path I want them to go to, which in this case means I want them to be redirected to the homepage. So this should give us the identical behavior we have right now, because we’re just hard-cording true in, and then it will change it to false and see if it works.
So I’m gonna come right here, and I’m gonna try to come to the dashboard. If I hit return, everything works, because it’s returning true. Now what happens though if this is false? So I’m gonna hit save, and now if I try to access the dashboard, if I hit return here, you can see it automatically redirected me to the homepage. So hopefully you can kinda see why I wanted to include these types of processes in a guide like this, because this isn’t part of the component lifecycle, but it is a part of the lifecycle of the user accessing a component. And so I thought that this would be something important, I thought it was missed out from a lot of the other tutorials I’ve seen.
So I’m going to now make this true again, so we can access the dashboard. And we can verify that by going to dashboard. And we just have one more function that I wanna go through.
So this next one is imagine they have a scenario where you have a user typing in a form, and they accidentally click to leave to a different page, not realizing that their data hasn’t been saved. This is pretty common use-case. Now, you might think that you would put that in the beforeDestroy hook. But that’s not really what beforeDestroy is for. That’s not it’s role. If you remember, the role of these two is really just to provide a way of cleaning up any processes. If you want to try to catch the user before they leave, the best and the recommended function to use is what is called the beforeRouteLeave function, it takes the same to, from, and next arguments.
And then from there what we can do is we can just ask the user a question. So I’ll say const answer = window.location or actually not location, this one’s window.confirm. And then, “Are you sure, your changes won’t be saved.”
And then from there all we’re gonna do window.cofirm gives us the ability to receive a Boolean value. So if they say okay, then it’s the same as storing true in answer, and if they say cancel, it’s the same as storing false. So if I say if the answer, which means if it’s true, then I want to allow them to go to whatever page it was they wanted to go to. Else, so if they hit cancel, then I wanna say next(false), which means that beforeRouteLeave is gonna say okay, it turns out that user didn’t wanna leave, and so do not allow them to leave. That’s why it’s called beforeRouteLeave.
So now … Oh, it looks like I have a typo. Oh, yeah, it’s a good reminder. Each one of these methods, and this is a case for all of Vue. Whenever you have these methods, they are objects. And so because at the end of the day export default is an object, it’s a set of key value pairs, then you have to make sure you list a comma after each one of those. But hitting save, that should fix it, and yes, we’re good to go.
So now we’re on the dashboard. Now if I click on home, you can see it has this little pop-up and it says, “Are you sure, your changes won’t be saved.” If I hit cancel, then nothing happens, we are kept on that page, and the user doesn’t lose their data. If I hit home, and hit okay, it allows me to be redirected. So that’s a way where you’re able to capture a user to make sure that they don’t do something like leave a page and lose data that they might’ve lost. And so that is a very helpful function.
So one last item I wanna leave you with. We’ve covered all of the methods, and we’ve discussed them, but the very first question that I had when I started going through these different elements was why do we need the beforeCreate and the created, the beforeMount and mounted? Why couldn’t we just use your created, mounted, and updated? And one thing I will say is, like I mentioned earlier, I really only use a few of these for every application I build. It’s very rare that I will use beforeMount, beforeCreate, or really even Created. The ones I use the most are gonna be mounted, beforeUpdate, updated, and then destroyed. And the task that I perform in each of those, and just as one side note, I do use these constantly but they’re not in lifecycle hooks, so I don’t count in the list, I use these in pretty much every single application a number of times. The beforeRouteEnter is the most common one I use, just because it allows me to have a guard in front of each component.
But going back to the lifecycle hooks, the mounted gives me pretty much all of the same access to data, and it gives me access to the lifecycle, or the point of the life of the component that beforeCreate/created, or beforeMount gives me.
So that’s the reason why I really use mounted for anything such as calling an outside API, storing the data, and then having it render on the page. That’s typically what I use mounted for. Occasionally I will use that inside of created, but most of the time I’m using that inside of mounted.
beforeUpdate is helpful for checking for data validation issues. So that’s what I use it for. So if you have a form with a number of validations and you do not want the user to be able to submit it and update the component without running through those validations, beforeUpdate is helpful through that.
Updated is helpful for updating the page after a change has occurred. So say the user hits save, they submitted some data, then updated allows me to capture that and then update the page automatically. And then like we talked about, the destroy items, and I typically just use destroyed, that’s usually where I am destroying things such as timers, or web sockets or anything like that.
So I know that was a longer guide, I really wanted to give you a single point of reference that you could look back at in the future, because this is something that I even have to look at quite often when I’m building out Vue apps, is seeing the full list of each one of these lifecycle hooks, and when they’re called. And so I wanted to give you a single guide that you could point to and say, “Okay, yeah, this is a full list of items, this is their syntax, their name, this is how they’re called, and this is how they work with components.”
So great job if you went through that, you should now have a good idea of how the lifecycle hook process works inside of Vue.js.
We’re first going to look in analyze at what attorney operator would look like in a React application. Then we’re going to go through two examples. We’re going to start off with a basic, just very similar to an if/else conditional. And then we’re going to see how you can implement compound conditionals directly into the ternary operator. As always, I’ll be following along in the comments section. So if you have any questions, comments, recommendations, anything like that, feel free to add those and I’ll get back to them as soon as I can. And if this video was helpful along your own coding journey, please give it a like and subscribe so I can keep on making more of them. So with all that being said, let’s dive into the code.
This is where the ternary operator comes in. I have to write this all on one line. And what a ternary operator allows you to do is to do that. Is to write an entire conditional on a single line. Here what I could say is, has permission and then I’m going to do a question mark, and then we’ll say active and I’m making all of this up right here. This is just an example to show what you may build. Then we’re going to get into real examples later on. So I could say active colon and then disabled. So what I have done here is I’ve provided a conditional. So this is the same thing as saying if, has permission then I want you to return active and if not, I want you to return disabled. This is the only way or the proper way I should say, for building a conditional in tools like React or Vue so that you can have some dynamic behavior built directly into your HTML and your JSX. So this is the main reason why ternary operators are so important to learn because if you are building out any kinds of real world front end application, you’re most likely going to have to build in something like this at some point or another.
Here I could say, if the age is greater than 25, then I want to console log, can rent a car and then right here we want to provide an else statement and then say I want that to be console log is not old enough yet. And that’s all that we want this function to do. So it’s pretty basic then I’m going to call this function by saying age, verification, if I say 15 here, if I save and then run it, it’s going to print out that the user is not old enough. If I change this to 55, and then run it again, now it’s going to say they can rent the car. So this is all working properly. It’s an incredibly basic function and this conditional is pretty much as basic as you can get. I did that on purpose. Anytime that I’m wanting to learn something new, especially something that might be a little bit more on the confusing side, I like to start off with a base case. We’re going to simply comment this out and then below here, I’m going to show you the syntax that will allow you to have a ternary operator.
We’re going to use the exact same logic, we’re just going to switch it up and use it with the ternary syntax. Now the way that you can do this is I’m going to store it in a variable. I’m going to say, let, answer, equals. Then here, I’m going to say age greater than 25, and then a question mark. Then I’m going to have it say the same thing. So I’ll say I can rent a car and then colon can’t rent a car. You could put is not old enough, whatever you want on that side. So that’s going to store it in a variable and then let’s simply print out the value of whatever that variable is. So we’ll say console log, answer and don’t worry, I know I typed all of that out pretty quickly we’re going to walk through exactly what the mapping is doing and everything.
Let me hit clear, save and then run it. And now you’re going to see it says, “They can rent the car.” So we’re getting the exact same answers before if I change this to five years old and hit run, it’s going to say they can’t rent the car. So this is working perfectly. This is the exact same behavior we were getting when we had that conditional on the five lines of code. So let’s walk through what’s going on. Right here, you can see the very first part of a ternary operator, is going to be the conditional. This is exactly the same as saying, if age is greater than 25 and so this is the first part you’re going to want to break your ternary operators, it’s easiest way to think of them is that they’re broken into three parts. The first part is the conditional. After the question mark, the second part is going to be, if that conditional is true, I want you to run this code.
Now if it’s not, you have the colon, and now this is going to be what happens if the condition was not met. If this is false, if the age is not greater than 25, then it’s going to skip everything here and then it’s going to parse the colon and say, “Okay, we want to return whatever is in this value here.” Now I also could have written out the console log statement here if you’re curious on why store this in a variable it’s really just for the sake of space because the ternary operators can get a little bit long. So I could have done something like this.
I could have just said age is greater than 25, then I could have said console log, can’t rent a car. Then here, console log again and then can’t rent a car, just like this. Now if I save this, clear it and run it, then you’ll see that we get the exact same behavior where it says, can’t rent a car. But typically, because of the way that this works, whenever you have … And let me get rid of all of that, just so it’s out of the way. So whenever you have a situation where you’re using a ternary operator, typically you do not want to put your console log statements actually in the true or the false values here. So let’s walk through the mapping just to make this clear, because I cannot tell you how … Don’t worry if this looks weird. I can’t tell you how many times a student has come up to me and says, I do not like using ternary operators, they don’t make any sense they look weird. I can tell you it just takes practice and what helped me the most when I was learning them is understanding what the mapping was.
Remember, the very first part of it is the first part of the conditional. We have, if age is greater than 25, we have age is greater than 25. They don’t have the if here, but you can just imagine that the F is right in front of it. then the question mark means that we’re now going to break into whatever happens when this is true and when it’s false. This right here is the true part. This is like dropping here into line three where it says, “Can’t rent a car. Then after this, this little colon here, you can imagine that this is the else. So this is exactly what we have here on line four where it says else and then it says, can’t rent a car. It’s exactly what we have here where it says is not old enough.
This is the basic way of implementing a turnaround operator. Like, you can see if you ever wanted to implement this in a React application or a Vue app, you couldn’t write the code like this. If you wanted to put it on one line directly into the HTML, then you’re going to have to write it like we have right here. So that’s why it’s important to know. I’m going to get rid of all of this and now let’s get into a little bit more of an advanced example. Before we get into this, I want to add the caveat that what I’m about to show you is important to understand that I would not recommend using it on a regular basis because the single ternary after you practiced it enough it will actually start to become very familiar to you and it’s not going to look as weird as it may look the very first time or second time that you’ve seen it.
What I’m going to show you now is, how you can implement compound logic. So multiple conditions all into the same ternary operator, and I can tell you this is going to look very weird. I’ve been doing this for a number of years. And when I see a compound conditional built into a ternary, it still takes me a while to kind of dissect the code to see exactly what’s happening. So I wouldn’t recommend doing this. But it is important to understand because I have run into a number of projects that I took over and I worked on, where the developer did do this. And it was important for me to understand what their logic and what their process was, because if I didn’t, then I’d be lost in the code base. So let’s walk through a more advanced example. I’m going to create another function here, I’m going to call it admin controls. So we’re going to say that the purpose of this function is to either show or hide admin controls.
Here I’ll say if user.admin and same thing we’re expecting a true or false value. And if the user is an admin or not. Then inside of here, I’m just going to console log and say, showing admin controls. Just like that. Then if they’re not an admin, we need to have some logic for that. So I’m going to say, if not, then I want to console log and say you need to be an admin. Then we also need to verify, we need to have a backup for if the user is just a guest user. Maybe the user hasn’t signed in. Here I’m going to put another conditional and say else and then we’ll put console log and then you need to be logged in, just like that.
Now if I save and I run this, we should have the, you need to be an admin. So we still have our showing admin controls and now it says, “You need to be an admin.” Everything there is working perfectly, they dropped into this because it was true. But then they were not an admin, so it fell into the else statement. Everything there is working. And last one, let’s say user three, and this is our guest user. So this is going to be a user who doesn’t have any values whatsoever. Just guess a user three and we’re just going to say that there, no. Now this user three they should return that you need to be logged in. Let me clear this, hit run and it should say, “You need to be logged in.” Which is perfect.
Everything here is working and our conditional is working. But let’s imagine that you need to put this in a ternary operator. Now this is going to look very weird. Once again, I would not recommend doing this at all, just because I think it leads to unreadable code. But if you ever come across a ternary operator that looks like this, you’re going to know exactly what it’s doing. I’m going to create a variable that we’re going to store this. So I’m going to say let, response equal and then here we are looking … Let me comment all this out, just so you don’t get a false reads on it. We have this user argument. I’m going to say user, then from there, we’re going to start off the same way we did with our basic examples.
It’s going to say, user, question marks where we’re going to first check, is the user true. Then this is where it gets weird. This is where we’re going to place another ternary operator inside of the very first statement. Because the way that this logic works is it’s going to check to see, is this the case? Is this user, do they exist? Same thing as saying user true and then we’re going to drop in to what happens if it’s true? Well what happens when it’s true in this example? Well we drop in to this second conditional. That’s exactly what we do here with the ternary operator. We’re going to say, user.admin and then we’re going to give another question mark. Because this is like asking that second question. We’re going to say, user admin and then here showing admin controls … and then we’re going to give what happens if they’re not an admin. You need to be an admin.
Now that we have that, now we need to go in to that final else. This is what happens if the user didn’t exist. Now we’ll say, you need to be logged in. Okay? We stored all of that in the response. Let’s just console log that, we say console log response. Hit Save, clear this and we should get all of the exact same answers. If I hit Run, there you go. You need to be logged in right above it was you need to be an admin and then showing admin controls. As you can see, this looks really weird. One thing I will say is unlike the if/else conditional, the spaces and having these carriage returns where you have all of the code on different lines, that may not be allowed in the JSX, or in your React or Vue application. But you actually can have carriage returns and it is valid code.
Let’s walk through what’s going on here, kind of line by line. Let’s start at the top. We’re checking to see if the user exists. That’s a same thing as just placing the user right there. Same thing as saying, user === true. If that is true, they will drop down into this next line here. If you prefer, if this is messing you up too much, then let me put this all on a single line again, just so we can read it all from left to right. Right here, what we’re doing is we’re saying is the user, do they exist? Yes. Okay. Well now it’s time to drop into a nother conditional.
One thing that does help me whenever I’m working with this kind of code, is I like to wrap the separate ones up in parens, just like this. This makes it a little bit easier and as you’ll see, this also works exactly the same way. Now if I hit Run, everything still works but I think at least in my opinion, this is a little bit easier to read and it shows that this is a nested conditional. Technically, you could keep on nesting them. You could have another conditional here, or you could have it in the else block. But to me, even having two of them is honestly a little bit too much. But it’s your world, you get to live in it. So build your conditionals however you want. But I just hope I wouldn’t have to take over your code base if that is what you decide on doing.
What we’re just getting back to, we have the user first conditional. They drop in to this conditional. This is the same thing as what we have here on lines three through seven. Where it says, “If this is the case, I want you to show the admin controls. If not, I want you to … You need to be an admin.” Same process. Then finally, if the user didn’t exist. If this was false, then it skips everything here until it finds the final colon and then it says you need to be logged in. What we wrote here on line 12 is exactly the same as what we wrote on line two to 10. As you could see the behavior is identical but the difference is, if you ever need to write your conditional all on one line, then this is the syntax that will allow you to do that.
Let’s talk about CSS media queries in this web development tutorial. And if you’ve never heard of what a media query is, that’s perfectly fine. We’re going to start from the ground up. A media query is a tool in CSS that allows for us to implement responsive design elements. When I say responsive, what I mean is what I’m going to show you right here. I have two nearly identical sites. One is responses and uses media queries, and the other one is not. We’re going to walk through, after this demo, we’re going to walk through the code and we’re going to implement a full media query for this homepage. Let’s first look at a media query based site. If I open this up, what I can do is it looks good on desktop and then if I were to access this on a mobile device, which I can mimic by just bringing this down here, you can see that the entire site readjusts. This is what someone coming on an Android or an iPhone would see. You notice how we have the logo has readjusted. It’s now at the top. And then we have the navigation elements are stacked on top of each other. And then the same thing with the contact information.
Then everything else has also readjusted. This is looking really good. This is the kind of experience you’d want to see on a mobile device. Now, if you open up a site that does not have the media query though, and then try to perform the same action, you’re going to get very different behavior. Notice now, if I take this down to the same size, that it does not readjust. Someone accessing the site’s going to load it up and they’re going to see this distorted looking page. They’re going to have to scroll to the right. A bunch of things are kind of shrunk in and overlapping. This is really not a good experience. This is the reason why media queries are so powerful. Now that we have a good idea on what they are, let’s walk through how we can implement them.
I have this page open and I have the code open for it right here. I’m going to start by creating a new style sheet here called media queries. This isn’t necessary, this is just because I want to be able to have all my media queries in one spot. It will also be easy for us to see them. Let me open that up and in the styles directory, I’m going to save a file called media queties.css. Then here, we’re going to be able to add all of those. Now, the syntax for using a media query is … it looks a little bit different if you’ve never used it before. It starts with a @ symbol. Then you say media. Then this is a method or a function. That means it takes an argument. The very first thing that we have to provide is the breakpoint. If I say medium max-width. Then I’m going to use 615 pixels. What this is going to do is this is going to say that whenever we have a screen that is below 615 pixels wide, which is a pretty standard size for using with smartphone devices, then I want you to apply these styles.
Now, whenever you’re using media queries, a trick to make sure that you are following is your media queries should be at the very end. They should be the last styles that you include. The reason for that is because if you have media queries and then you call other styles after that, they will override it. You need to make sure you call that at the very end. What this is going to do is the browser’s going to look, it’s going see all of these media queries, and it’s going to check and say, “Okay, these are the styles I am going to apply, and I’m going to run these if the screen is 615 pixels or less.” You could do this for any of them. Let’s just test this out.
If you look at the index here in the navigation wrapper, you can see that we have navigation wrapper and then we have all of these items inside of it. We have a left column, a center column div, and then a right column. I think this is going to be a great place to start. If I say navigation-wrapper. Then inside of here, I’m going to change the flex direction. Instead of having the default row, I’m going to change it to column. Then I also want to update the height so it’s 100%. Let’s see what this does for us on our site that previously was not working on mobile. Let me open this up in a new browser window. Now, if I shrink this down, you can see that when we hit that breakpoint, you see how this got readjusted. Before, that was not working. Before, it just simply went to the side and then it didn’t shrink down and it didn’t stack it on top of each other like that.
That means that our media query is firing and it’s working. Now, we still have some work to do, because this doesn’t look very nice. We still have to adjust some of the other items. I don’t want the phone number here at the top. I want to have the logo at the top. We’re going to be able to leverage Flexbox in order to make that possible. I’m just going to take this down to about right here, about this size. Now, when we switch back, we’re just going to be able to look at that. I’m also going to keep the code open at the same time, so that we can save some time and just look at it simultaneously. Okay, now that we have our navigation wrapper updated, I want to talk about a very powerful tool inside of Flexbox that you may or may not be aware of.
Flexbox gives you the ability, not simply to line out and align your items in a really nice and easy manner, it also gives you the ability to change the order. That is how we are going to readjust the order that these elements are shown. This is one of my favorite parts about Flexbox. Right here, if you remember we have our left column, our center column, and then our right column. What I can do is say navigation wrapper. Then I want to grab the left column, just like this. Then inside of here, I want to change the order to two. That’s going to allow us to change the default order, because usually the order is simply the order that it is declared in the HTML. But what we can do is we can actually override that using Flexbox. I’m also going to add some margin top and some margin bottom. Let me do 10 pixels on the top and then margin bottom, I’m going to go with, let’s say 15 pixels.
That’s all we need the left column. Now, for the center column, remember the center column is the logo. The … if you want to take a look at it … This is the final site, but this also is what we started with. Here you can see that the left column is the phone number and the hours. The center column is the nav component and logo. Then the third column is this address here. That’s what we’re looking to adjust. I want to take the center column and I’m going to change the order here so that the order’s going to be one. Then I also want to change the width. The width here is going to be 100%. Then lastly, we want to grab the right column and, as you may have guessed, since we used two on the left column, for the right column, we want to use three here. Then I’m going to also just add some margin on the top. Here I’m going to say 15 pixels.
Now, this isn’t going to be perfect yet, because we still have those links that we need to fix, but this might get us a little bit closer. Let’s see. Hit refresh. You can see that is looking much better. Do you see how we have this logo now that is at the very top? Our images, or I’m sorry, our links here, that these need to get fixed. That’s what’s pushing everything over. But we can see that everything now is in the correct order. That is looking really nice. As you can see, all we have to do is because we leverage Flexbox, we’re able to alter that order and control exactly how we wanted the page to be rearranged. Then let’s switch over to the index HTML page. Let’s see, we have a class of links wrapper. Then a nav link inside of each of those.
That’s going to be the next class that we’re going to add to our media query here. Now, what we can do is we’ll say links wrapper. Then here inside of it, if you want … if you’re using Flexbox and you want to change the order so it’s no longer is showing from left to right, but instead it goes from top to bottom, you can simply change the flex direction. We’re going to change that to column. Then I’m also going to add some margin to the bottom. For that, we’ll go with 20 pixels. Then let’s also update the nav link, but before we do that, let’s just see where we’re at. If I hit refresh that is looking much better. See, that this is exactly what we’re looking to do. That is how we’re able to leverage media queries to be able to adjust dynamically how the page is laid out.
I’m really liking that. Now, let’s go to our links wrapper. We’re going to select all of the nav links, the nav link class. Inside of here, I’m going to just add … They’re stuck a little bit close together. That would be hard for someone on mobile to click the right button. Let’s add some margin to the top and bottom. Then from there, we’re going to update the font size. Let’s go with 1.5em. Then lastly, we’re going to adjust the width to be 100%. Now, if you hit save, come back, hit refresh, there you go. Now, what we’ve done is we’ve completely changed the layout of this nav bar so that it matches exactly what we’re wanting on a mobile device. Imagine you are building out this website and you’re building it for a restaurant, just like we have here, and someone clicks on the link from Yelp. They are going to want to see something that looks like what we have here, not have distorted site where they don’t even know where to click or anything like that. They want to have something that really fits with that mobile user experience.
We’re able to leverage media queries in order to do that. Let’s just review, really quick, what we’ve done. The syntax, once again, for a media query is using the @ symbol, the work media. Then defining the width. You can have multiple media queries. You could have a media query that is for smartphones. Then you can adjust and have a media query that is for iPads or tablets. You could have as many media queries as you want. Then the page would dynamically change. This is almost kind of like a conditional. You can think of this as being a way that you can tell the browser that these are different rules that you want it to follow whenever the user is on a different screen size. Then from there, you simply have to call that in the HTML, just like we did right up here and it’s going to work and it’s going to readjust.
Then lastly, using tools like CSS Grid and Flexbox give you the ability to control how you want the layout to change. If you weren’t using a tool like that, it’d be much harder to change the order, like we have right here. But because you have those kinds of tools in place, you can simply readjust the entire page based on the screen size.
Let’s dive into how we can use images in HTML. And specifically, we are gonna take a logo and we’re gonna place it here at the top of this nav bar. We’re gonna see how we can import the image and how we can select it using CSS and then also how we can style it and customize its size. If you want to, you can use your own logo or you can use one of the demo ones that I have here, and I’ll include a link to the show notes for you.
The very first thing you can do is open this up and you can see we have a dark version and then a white version. And for this specific background, we really need to use the white version. So right-click on this and then click Save Image As and you can keep the name exactly the same and then place it inside of your project. Now, you can just hit Save right now, but then we’ll also customize exactly where it’s at so that we can see the path and so we can organize it properly.
So if we switch back here and then go to the code, I’m gonna place this above all the other nav links here and let’s just call it Banner Image. So this is going to be a wrapper div. And then I want to use an image tag. So if you’re using Visual Studio Code, you can type, “IMG,” hit tab, and this is gonna give you the values that you want. Now because we place this at the root of our project, you can see that we have this Dev Camp Fantastic Fries logo dash white right here. And so we could just grab this value. And so let me actually copy that name so that I’m not typing it out verbatim.
And then you can place that inside of this SRC tag. Now this SRC tag, it stands for Source, which means that we’re telling the image tag that the source of this image is this path. And then we’ll play around with how we can place this image inside a different part of the project. Now we also have this ALT tag. So here I’m going to say the logo. Now technically you could say anything that you wanted right here. The rational for the ALT tag is there’s a couple reasons. One is if someone has disabled images in their browser, then the ALT tag will show up instead of the image, but the most common reason for using the ALT tag is for accessibility reasons.
So if someone, say someone whose blind is going through your site and the way it works is there’s systems out there that will read things like the ALT tags in your content. If you leave the ALT tag blank, then they’re not gonna know that a logo was there. So that’s part of the reason. Google also reads through this for search engine optimization reasons. So it’s always good to put some kind of value here that describes what the logo is or that a logo is there. So that is gonna give us our basic import so let’s go back and hit refresh. And wow, you can see, that is imported, but that’s definitely not what we’re looking for. And that’s fine, that’s what were expected.
This is gonna take a. by default, the way that HTML works is it brings in the image and it does not do anything to it. It doesn’t try to make it fit or anything like that. That is our job. So now let’s see how we can select this image. So we know that we have a class here called “Banner Image.” And there are a couple different ways that we could customize it. So I could come here and … let me give us a little bit more room. So I could come in the tag itself and just say that I want to provide a hard coded with in line.
So here I could say “With” and for this kind of size, the value that I saw looked the best was something like 216 pixels. And then let’s give it a hight and the height here, you can combine pixels and percentages. So for the height here I could say just 100%. What this means is that we are controlling the width, we’re saying how wide it should be, and then we’re telling the height to just be automatic. So I’ll hit save and now if I hit refresh, you can see that works and that looks really good. And that’s perfectly fine. I usually don’t do it this exact way.
The approach I usually take is to apply a actual CSS class to it. So if I have my banner image here, what I can do is come down to the bottom of the CSS file and say “Banner dash image” and then I want to select the image tag inside of that. And now I can apply the exact same rules. So here I can say with and we wanna go with that 216 pixels and then for the height 100%, hit save, go back and hit refresh, and you can see that is working properly. So that’s just my own personal preference. Part of the reason is because I don’t really like my images to get really messy and the more code that you put inside of this tag, the longer it’s gonna be for you to find it when you need to fix it and also just starts to look a little bit cluttered.
So I’d much rather put it inside of a style tag. But that is how you can import and then customize an image using HTML. And there’s only one more thing that I wanna do before we end this guide and that is I want to place this inside of a little bit more logical place. Because right now, you can see that I have the image at the root of the project, but this doesn’t make a lot of sense because if I start bringing in dozens or hundreds of images, this is gonna start to get really messy. So instead what I’m gonna do is I’m gonna create a new tag, or a new folder here.
I’m just gonna call it “images” and then inside of images, I want to pass in another folder. So I can right click on it and click new folder. And here I’m gonna say “logos.” And then what I can do is I can just click and then drag this in and it says, “Are you sure you wanna move this?” And so yes, I say I want to move it. Now this will break the site. So if I hit refresh here you can see … oh, one thing that is cool. You see that little ALT tag is showing up. So if the image is not available, it will show the ALT tag, but now we have a broken image and it’s because we need to update the path.
So here I will say that I want it to find it in the images directory in logos and then it will go and it will find the image file. Switching back to the browser, hitting refresh. You can see that image is back and it is working properly.