DEV Community

Umeh Chisom for Auvira Systems

Posted on

Building a "Privacy Shield" in React: How I obfuscated financial data for working in public

As a solo founder building AccIQ (a local-first financial IDE), I spend a lot of time working in coffee shops and coworking spaces.

The problem? I’m often looking at my own cash flow, runway, and burn rate. Having those numbers visible on a 14-inch screen in a crowded cafe is... stressful.

I needed a way to "hide" the data instantly without breaking the UI or reloading the page. So, I built a global Privacy Shield.

Here is the simple React + Tailwind pattern I used to build it.

The Logic: Blur, Don't Hide

The most common way to hide data is to replace it with asterisks (****). But that breaks the visual rhythm of a dashboard. It makes it hard to see if a column is balanced or if a graph is trending correctly.

Instead, I chose to use CSS Filters. By applying a blur, you maintain the "shape" of the data (you can tell if it's a large number or a small one) without it being legible to someone sitting at the next table.

  1. The Global State I used a simple React Context (or a global state hook) to manage the isPrivacyMode boolean.
const [isPrivacyMode, setIsPrivacyMode] = useState(false);

const togglePrivacy = () => 
setIsPrivacyMode(!isPrivacyMode);
Enter fullscreen mode Exit fullscreen mode
  1. The Tailwind Pattern The implementation is incredibly clean thanks to Tailwind's utility classes. I created a reusable PrivacyText component that wraps any sensitive integer.
interface PrivacyTextProps {
  value: string | number;
  className?: string;
}

const PrivacyText = ({ value, className = "" }: PrivacyTextProps) => {
  const { isPrivacyMode } = usePrivacy(); // Your global state hook

  return (
    <span 
      className={`
        transition-all duration-300 ease-in-out
        ${isPrivacyMode ? 'blur-md opacity-40 select-none pointer-events-none' : 'blur-0 opacity-100'}
        ${className}
      `}
    >
      {value}
    </span>
  );
};
Enter fullscreen mode Exit fullscreen mode

Why this works:
blur-md: This is the sweet spot. It makes text completely unreadable but keeps the layout intact.

opacity-40: Adding a slight transparency makes the blurred text look "disabled," signaling to the user that the shield is active.

select-none: This prevents someone from accidentally (or intentionally) highlighting the text to reveal it.

transition-all: A smooth 300ms transition makes the toggle feel like a premium feature rather than a glitchy UI jump.

  1. The Keyboard Shortcut

A privacy shield is useless if you have to hunt for a button while someone is walking behind you. I mapped it to a global keyboard listener (typically Cmd + Shift + P).

useEffect(() => {
  const handleKeyDown = (e: KeyboardEvent) => {
    if (e.metaKey && e.shiftKey && e.key === 'P') {
      togglePrivacy();
    }
  };
  window.addEventListener('keydown', handleKeyDown);
  return () => window.removeEventListener('keydown', handleKeyDown);
}, []);
Enter fullscreen mode Exit fullscreen mode

The Result

This small feature has become one of the most talked-about parts of AccIQ. It’s a "quality of life" detail that shows you actually understand your users' environment.

You can see the Privacy Shield in action (and toggle it yourself) in the Finance-OS demo here:

👉 Launch AccIQ (Guest Mode)

I'm curious—what other "public-friendly" UI features have you seen or built? Let me know in the comments!

Top comments (0)