Part 70: Implementing Sign Out Functionality in a Next.js NavBar
[Pages] Authentication

In this blog post, we'll walk through adding sign-out functionality to a NavBar component in a Next.js application. This involves handling user authentication states and ensuring cookies are managed correctly for security.
Adding Sign Out Functionality
The NavBar component already fetches and displays user data from the /api/user route, showing the user's name alongside a "Sign Out" button. However, clicking "Sign Out" currently does nothing. Let's fix that by adding the necessary logic to remove the authentication cookie and update the application state.
Step 1: Handle Sign Out in the NavBar
First, we'll add an onClick event handler to the "Sign Out" button. This handler will call a function named handleSignOut, which we will define shortly.
// components/NavBar.js
import Link from 'next/link';
import { useEffect, useState } from 'react';
import { fetchJson } from '../lib/api';
function NavBar() {
const [user, setUser] = useState();
useEffect(() => {
(async () => {
try {
const user = await fetchJson('/api/user');
setUser(user);
} catch (err) {
// Handle unauthenticated state
}
})();
}, []);
// Sign Out handler
const handleSignOut = async () => {
await fetchJson('/api/logout');
setUser(undefined); // Reset user state
};
console.log('[NavBar] user:', user);
return (
<nav className="px-2 py-1 text-sm">
<ul className="flex gap-2">
{user ? (
<>
<li>{user.name}</li>
<li>
<button onClick={handleSignOut}>Sign Out</button>
</li>
</>
) : (
// Other NavBar items
)}
</ul>
</nav>
);
}
export default NavBar;Step 2: Create a Logout API Route
Since our JWT is stored as an httpOnly cookie, we cannot modify it directly from the client side. Instead, we'll create a new API route, /api/logout, to handle removing the cookie securely on the server side.
// pages/api/logout.js
import cookie from 'cookie';
function handleLogout(req, res) {
res.status(200)
.setHeader('Set-Cookie', cookie.serialize('jwt', '', {
path: '/api',
expires: new Date(0), // Set expiry in the past to remove cookie
}))
.json({}); // Send empty JSON response
}
export default handleLogout;Step 3: Remove the Cookie
In our API route, we use the cookie module to manipulate the cookie headers. Setting the expires date to a past date effectively instructs the browser to discard the cookie, thus logging the user out.
Step 4: Update the Application State
Once the logout request succeeds, we reset the user state in the NavBar component to undefined, which indicates the user is no longer authenticated. This update triggers a re-render of the component, replacing the user-specific content with a "Sign In" link.
Testing the Implementation
To ensure everything is working correctly:
Sign In: First, sign in to your application to set the JWT cookie.
Sign Out: Click the "Sign Out" button in the NavBar.
Check the Network Tab: Open Developer Tools and observe the network requests. You should see a request to
/api/logoutand aSet-Cookieheader with an expired date.Verify Cookie Removal: Check the Application tab in Developer Tools to confirm that the JWT cookie is no longer present.
Conclusion
We've successfully implemented a sign-out functionality by creating a logout API route that manages the JWT cookie on the server side. This approach ensures that user authentication states are managed securely and efficiently. In upcoming posts, we'll explore optimizing API requests and caching responses using libraries like React Query to enhance performance further. Stay tuned for more insights on building robust Next.js applications!
Last updated