Let’s provide a way to log out.

Next to the

<li className='username'>{user}</li>

snippet, I’m going to add this:

<li>
  <a
    href='#'
    onClick={async () => {
      await axios.post('/api/auth/logout')
      setUser(null)
    }}>
    Log out
  </a>
</li>

which is very similar to the Sign up and Log in buttons.

When the Log out button is clicked, it calls the /api/auth/logout endpoint with a POST request. When the call is over, it resets the session user property in the frontend, using setUser().

We need to define this function, right after the user declaration:

const setUser = useStoreActions(actions => actions.user.setUser)

Since we use Axios, I’m also going to add

import axios from 'axios'

on top of the file. We already have this library installed.

We also need to add a React fragment to wrap the 2

  • elements we added.

    This should be the full code of the component:

    components/Header.js

    import Link from 'next/link'
    import axios from 'axios'
    
    import { useStoreActions, useStoreState } from 'easy-peasy'
    
    const Header = () => {
      const setShowLoginModal = useStoreActions(
        actions => actions.modals.setShowLoginModal
      )
      const setShowRegistrationModal = useStoreActions(
        actions => actions.modals.setShowRegistrationModal
      )
      const user = useStoreState(state => state.user.user)
      const setUser = useStoreActions(actions => actions.user.setUser)
    
      return (
        <div className='nav-container'>
          <Link href='/'>
            <a>
              <img src='/img/logo.png' alt='' />
            </a>
          </Link>
    
          <nav>
            <ul>
              {user ? (
                <>
                  <li className='username'>{user}</li>
                  <li>
                    <a
                      href='#'
                      onClick={async () => {
                        await axios.post('/api/auth/logout')
                        setUser(null)
                      }}>
                      Log out
                    </a>
                  </li>
                </>
              ) : (
                <>
                  <li>
                    <a href='#' onClick={() => setShowRegistrationModal()}>
                      Sign up
                    </a>
                  </li>
                  <li>
                    <a href='#' onClick={() => setShowLoginModal()}>
                      Log in
                    </a>
                  </li>
                </>
              )}
            </ul>
          </nav>
    
          <style jsx>{`
            ul {
              margin: 0;
              padding: 0;
            }
    
            li {
              display: block;
              float: left;
            }
    
            a {
              text-decoration: none;
              display: block;
              margin-right: 15px;
              color: #333;
            }
    
            nav a {
              padding: 1em 0.5em;
            }
    
            .nav-container {
              border-bottom: 1px solid #eee;
              height: 50px;
            }
    
            img {
              float: left;
            }
    
            ul {
              float: right;
            }
    
            .username {
              padding: 1em 0.5em;
            }
          `}</style>
        </div>
      )
    }
    
    export default Header
    

    If you click it now you’ll get an error, because we haven’t defined an /api/auth/logout` server side route.

    Let’s do it by adding a this line to our server.js file:

    server.post('/api/auth/logout', (req, res) => {
      req.logout()
      req.session.destroy()
      return res.end(JSON.stringify({ status: 'success', message: 'Logged out' }))
    })
    

    We call req.logout() and req.session.destroy(), then we send a successful message to the client.

    If you try to log out now, you should see that the navigation bar changes back to the normal state.


    Go to the next lesson