How to Show and Hide Links When Logged In
Over the next couple of guides we're gonna work through how we can add some dynamic behavior to the website just by looking at the logged in status.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

So, we're going to see specifically how we can update the navbar based on if a user's logged in or not and I'm gonna break this into two guides because we have to think about this in two different ways. We have to think first of what the user sees, so say that we want this Blog link here to only show up if you're logged in.

Now, this will be available to everyone in the final product but we haven't created the Portfolio Manager or the Blog Manager, so I don't wanna spend time in creating those 'til they're actually needed, so we're gonna use this Blog link as the test.

So let's say that that link should only show up when you're logged in. Well, that's one part of it, we also though need to think about the route definition itself. So in this guide, we're gonna walk through first how to hide the link, and then in the next guide, we'll see how we can actually get rid of the route entirely.

So I'm not logged in, you can see that by my logged in status, so let's switch to Visual Studio Code here and let's take a look at everything that needs to be done. So we have our return statement which is bringing in the nav-wrapper.

Now what I'd like to do is instead of writing too much code directly inside of here, I would like to create a function that will work if the user is logged in or if they're not, so what I can do here is I'm actually gonna get rid of all of this code and I should say I'm cutting it and I'm gonna put it up here.

So, I'm gonna paste this up here and then from here what we can do is actually implement the function itself. And so, the way that you can do this inside of a functional component is very similar to defining any kind of function. So I can come here and say const and let's call this dynamicLink and this is gonna be an arrow function. It's gonna take in two arguments, it's gonna first take in the route and then the linkText.

That way we can create as many of these as we want and so, I'm gonna say route and linkText and that's gonna be an arrow function. So, it is going to return all of this JSX code, so I can take all of this that I cut, put it inside of the return statement and that should work.

navigation-container.js

const NavigationComponent = props => {
  const dynamicLink = (route, linkText) => {
    return (
      <div className="nav-link-wrapper">
        <NavLink to="/blog" activeClassName="nav-link-active">
          Blog
        </NavLink>
      </div>
    );
  };

So now let's test this out before we even get into the true dynamic behavior, so I can come down here, right where Blog used to be, so let's say this is in Contact, yeah, so this is gonna be right here and now inside of the curly braces, I can say dynamicLink and then say /blog, just like we had before and then we can just call this Blog.

{dynamicLink("/blog", "Blog")}

Okay, so let's see if that worked if we're able to extract all of that code out or not. So, now if you come back here, hit refresh, you can see Blog's still there and it is still working properly, so far so good. Now you can see this is much easier to manage than if we had all of this code up here. I'm gonna show you in one second exactly why this is necessary because we're gonna write a multi-line turnery operator which if you've never done that before, it looks very weird.

So, we wanna grab props from the app component, so we have it so we can receive props but now we need to actually send them, so if you go to the app component, go into the NavigationContainer and now let's add a new prop of loggedInStatus, set it equal to curly braces, this.state.loggedInStatus just like that,

<NavigationContainer loggedInStatus={this.state.loggedInStatus} />

hit save and now we'll be passing that prop to the NavigationComponent and with that in place, we can now add a conditional here. So, this might look a little weird if you've never seen it before, I'll give us a little bit of room and so, inside of the curly braces, I'm gonna say props.loggedInStatus, just like this, is triple equals to LOGGED_IN and then I'm gonna add a question mark, so this is the same kind of turnery operator we've seen before, this is the same thing as us saying okay, is something true? If it is, then do this, and if not, do something else.

{true ? "do this" : "do something else"}
{props.loggedInStatus === "LOGGED_IN" ? (dynamicLink("/blog", "Blog")}

So, remember, this is the same structure. We're not changing that at all, we're just adding quite a bit more code which is the reason why it can be a little confusing. So, the very first thing is this dynamicLink. That is going to be what we wanna show if it's true, so if loggedInStatus from props is equal to LOGGED_IN, then I want to have and show this dynamicLink.

Now if not, I just want null, so that is where I'm gonna add the colon and say null, so we're not gonna show anything at all right there, so let me get rid of our demo, hit save, prettier has formatted it very nicely, you can see it even wrapped the dynamicLink in parens just to make it clear that that's exactly what's being returned there and I believe this should be all that we need.

{props.loggedInStatus === "LOGGED_IN" ? (
  dynamicLink("/blog", "Blog")
) : null}

So, if I switch back here, you can see, if you hit refresh, the Blog link is now gone, so we're not logged in and the Blog link is gone which is exactly what we're looking to do. If you hit auth, go to auth and then log in, hit Login, now you can see the Blog link is there, so all of that is working perfectly.

Now, there still is one issue and I have to get out incognito mode and open it back up. It'll be very nice when we build out our log out feature in a few videos, it'll save us some time, so you can see I'm NOT_LOGGED_IN, and the link's not there but if I just go to /blog and go to the route itself, you can see that still exists.

So, even though we're NOT_LOGGED_IN, and we're saying that this should not be accessible, it still is and so, that would definitely be a pretty big security vulnerability, so in the next guide we're gonna see how we can show and hide the actual routes, so where we will pull out the entire route definition if a user is not logged in.

Resources