DEV Community

Stephen Gbolagade
Stephen Gbolagade

Posted on

Adding a "Last Used" Badge to Your Website Login Page

Your users may get confused the next time they want to log in to your website due to multiple authentication methods. Adding a “Last Used” badge - as popularly seen on websites like lovable.dev, can fix this UX problem.

While offering multiple authentication methods is beneficial, users often face a common challenge: "What did I sign up with—Google or email?" This goes beyond user preference; it's a valid user experience (UX) concern.

This small friction can lead to failed login attempts, repeated password resets, and users abandoning your software altogether.

Adding a simple helper badge like "Last Used" or "Last Login" can solve this issue once and for all. In this post, I'll show you how to implement it. Although I'll use Next.js to demonstrate, the same logic applies to any frontend framework.

Here's what we'll do:

  • 1. - Store the user’s preferred authentication method in LocalStorage.
  • 2. - Create a “Last Used” Badge component.
  • 3. - Add the component to the login page.

Disclaimer: I assume you're familiar with frontend development and have a project set up, so I won’t cover basics like starting a React.js project or handling states. I'll focus on the simple approach to adding the "Last Used" Badge, and you can complete the remaining logic yourself.

Let's start!

Step 1: Setting Up the Login Component

First, create a basic login component with multiple authentication options. The email and password fields aren't displayed initially—instead, a button acts as a placeholder. When clicked, it hides other methods and shows the email/password form.

It's also best practice to create reusable buttons for each authentication flow, e.g., . The badge component will be absolutely positioned for each method to improve UX.

'use client';

import { useState, useEffect } from 'react';

export const LAST_USED_KEY = '_app_last_login_method';

export default function LoginPage() {
  const [lastUsedMethod, setLastUsedMethod] = useState(null);
  const [showEmailFields, setShowEmailFields] = useState(false);

  // Load last used method on component mount
  useEffect(() => {
    if (typeof window !== 'undefined') {
      const stored = localStorage.getItem(LAST_USED_KEY);
      setLastUsedMethod(stored);
    }
  }, []);

  // When email button is clicked, show the form fields and hide other auth methods
  const handleEmailLogin = () => {
    setShowEmailFields(true);
  };

  if (showEmailFields) {
    return (
      // Email fields component (implement your form here)
      <div className="max-w-md mx-auto p-6 bg-white rounded-lg shadow-md">
        <h2 className="text-2xl font-bold mb-6 text-center">Sign In with Email</h2>
        {/* Add your email/password form fields, submit button, etc. */}
      </div>
    );
  }

  return (
    <div className="max-w-md mx-auto p-6 bg-white rounded-lg shadow-md">
      <h2 className="text-2xl font-bold mb-6 text-center">Sign In</h2>

      {/* Email/Password Login */}
      <div className="relative mb-4">
        <button 
          className="w-full p-3 border border-gray-300 rounded-lg hover:bg-gray-50"
          onClick={handleEmailLogin}
        >
          Continue with Email
        </button>
        {lastUsedMethod === 'EMAIL' && <LastUsedBadge />}
      </div>

      <div className="text-center text-gray-400 text-sm mb-4">OR</div>

      {/* Google OAuth */}
      <div className="relative">
        <button 
          className="w-full p-3 border border-gray-300 rounded-lg hover:bg-gray-50 flex items-center justify-center"
          onClick={() => handleGoogleLogin()} // Define handleGoogleLogin below
        >
          <GoogleIcon className="w-5 h-5 mr-2" /> {/* Assume GoogleIcon is imported */}
          Continue with Google
        </button>
        {lastUsedMethod === 'GOOGLE' && <LastUsedBadge />}
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Now, let’s create the badge component.

Step 2: Creating the "Last Used" Badge Component

The badge provides visual feedback about the user's last used method:

const LastUsedBadge = () => {
  return (
    <div className="absolute -top-2 -right-2 z-10">
      <span className="inline-flex items-center px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full border border-blue-200">
        Last used
      </span>
    </div>
  );
};

Enter fullscreen mode Exit fullscreen mode

The design is up to you. You can use a Badge component from libraries like Shadcn UI if preferred.

Step 3: Tracking Authentication Methods

Implement logic to save and retrieve the user's preferred method. Use a utility function to store it:

// Utility function to save login method
const saveLoginMethod = (method) => {
  if (typeof window !== 'undefined') {
    localStorage.setItem(LAST_USED_KEY, method);
  }
};

// Email/Password authentication handler (add to your form submit logic)
const handleEmailSubmit = async (formData) => {
  try {
    // Your authentication logic here
    const response = await signInWithEmail(formData);

    if (response.success) {
      // Save method on successful login
      saveLoginMethod('EMAIL');

      // Redirect to dashboard
      router.push('/dashboard');
    }
  } catch (error) {
    console.error('Email login failed:', error);
  }
};

// Google OAuth handler
const handleGoogleLogin = async () => {
  try {
    // Initiate OAuth flow
    const response = await signInWithGoogle();

    if (response.success) {
      // Save method on success
      saveLoginMethod('GOOGLE');

      // OAuth will handle redirect
    }
  } catch (error) {
    console.error('Google login failed:', error);
  }
};
Enter fullscreen mode Exit fullscreen mode

If your app is highly security-sensitive, consider storing this in an httpOnly cookie via server actions or API routes instead of LocalStorage. I'm not aware of major security concerns with storing just the method type, but always evaluate based on your needs.

Step 4: Handling OAuth Redirect Flows

OAuth involves redirects, which can complicate tracking. Here's how to handle it.

For client-side OAuth:

// For providers that allow client-side completion
const handleGoogleLogin = async () => {
  // Save preference before initiating OAuth
  saveLoginMethod('GOOGLE');

  // Initiate OAuth flow
  window.location.href = '/auth/google';
};
Enter fullscreen mode Exit fullscreen mode

For server-side callbacks with client notification (in Next.js):

// In your OAuth callback handler (/api/auth/callback/google.js)
export default async function handler(req, res) {
  try {
    // Handle OAuth callback logic
    const { user, session } = await processOAuthCallback(req);

    if (user) {
      // Redirect with login method parameter
      res.redirect('/dashboard?login_method=GOOGLE');
    }
  } catch (error) {
    res.redirect('/login?error=oauth_failed');
  }
}
Enter fullscreen mode Exit fullscreen mode

Then, process the parameter on the client:

// Hook to process login method from URL params
const useLoginMethodTracker = () => {
  const router = useRouter();

  useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const loginMethod = urlParams.get('login_method');

    if (loginMethod) {
      saveLoginMethod(loginMethod);

      // Clean up URL
      const url = new URL(window.location);
      url.searchParams.delete('login_method');
      window.history.replaceState({}, '', url);
    }
  }, []);
};

// Use in your dashboard or protected pages
export default function Dashboard() {
  useLoginMethodTracker();

  return <div>Welcome to your dashboard!</div>;
};
Enter fullscreen mode Exit fullscreen mode

Now, try to log out and log in to your website, log out again, and try to log in, you should see something like this:

Adding

That's all, and you're done!

Website "Last Used" Best Practices and Considerations

Security

  • Store only the authentication method, not sensitive data.
  • Use sessionStorage for more sensitive apps.
  • Implement CSRF protection for all methods.

Privacy

  • Clearly inform users about locally stored data.
  • Allow users to clear this preference.

Accessibility
Ensure badges don't interfere with screen readers.
Provide ARIA labels.
Test with keyboard navigation.

Conclusion

Adding a "Last Used" badge to your login page is a small enhancement with significant UX benefits. By reducing friction and providing visual cues, you create a more intuitive experience that boosts user engagement and retention.

The implementation is straightforward, requiring minimal code changes for maximum impact. As authentication evolves, these thoughtful touches will become essential.

Do you have any questions?

Top comments (0)