DEV Community

Cover image for 🪟 How to Open and Communicate with a Popup Window in React (with TypeScript)
Taron Vardanyan
Taron Vardanyan

Posted on

🪟 How to Open and Communicate with a Popup Window in React (with TypeScript)

Opening a popup window in React isn't hard—but managing communication between your app and that popup can get tricky. In this article, you'll learn how to:

  • Open a new browser window (popup)
  • Send data from the parent React app to the popup
  • Detect when the popup is closed

We’ll be using React Function Components with TypeScript to make this solution strongly typed and future-proof.


🧠 What You’ll Learn

  • How to open a popup window with specific dimensions
  • How to communicate with that popup window using postMessage
  • How to watch for popup closure using setInterval
  • A clean, reusable TypeScript implementation

📦 Let’s Build It!

1. Create the Popup Component

This component will live inside the popup window and receive data from the parent window using message events.

// PopupPage.tsx
import { useEffect, useState } from 'react';

const PopupPage = () => {
  const [message, setMessage] = useState<any>(null);

  useEffect(() => {
    const handleMessage = (event: MessageEvent) => {
      // Optionally: restrict to same-origin in production
      if (event.origin !== window.location.origin) return;

      console.log('Received message:', event.data);
      setMessage(event.data);
    };

    window.addEventListener('message', handleMessage);
    return () => window.removeEventListener('message', handleMessage);
  }, []);

  return (
    <div style={{ padding: 20 }}>
      <h2>Popup Window</h2>
      <p>
        <strong>Message from parent:</strong>
      </p>
      <pre style={{ background: '#eee', padding: '10px' }}>
        {message ? JSON.stringify(message, null, 2) : 'No message received'}
      </pre>
    </div>
  );
};

export default PopupPage;
Enter fullscreen mode Exit fullscreen mode

2. Create the Main App with Popup Logic

This component handles the logic to open the popup, send a message, and watch for closure.

// App.tsx
import React, { useRef, useState } from 'react';

const App: React.FC = () => {
  const popupRef = useRef<Window | null>(null);
  const timerRef = useRef<NodeJS.Timer | null>(null);
  const [popupOpen, setPopupOpen] = useState(false);

  const openPopup = () => {
    if (popupRef.current && !popupRef.current.closed) {
      popupRef.current.focus();
      return;
    }

    const width = 400;
    const height = 300;
    const left = window.screenX + (window.outerWidth - width) / 2;
    const top = window.screenY + (window.outerHeight - height) / 2;

    popupRef.current = window.open(
      '/popup',
      'MyPopup',
      `width=${width},height=${height},left=${left},top=${top}`
    );

    if (popupRef.current) {
      setPopupOpen(true);
      startWatcher();
    }
  };

  const sendMessage = () => {
    popupRef.current?.postMessage('Hello from parent!', window.origin);
  };

  const startWatcher = () => {
    timerRef.current = setInterval(() => {
      if (!popupRef.current || popupRef.current.closed) {
        clearInterval(timerRef.current!);
        timerRef.current = null;
        popupRef.current = null;
        setPopupOpen(false);
        alert('Popup was closed');
      }
    }, 500);
  };

  return (
    <div style={{ padding: 20 }}>
      <h1>React Popup Communication (TS)</h1>
      <button onClick={openPopup}>Open Popup</button>
      <button onClick={sendMessage} disabled={!popupOpen}>
        Send Message
      </button>
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

🛣️ Setting Up the Route for the Popup

If you're using React Router, you can route the popup like this:

// index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import App from './App';
import PopupPage from './PopupPage';

const root = ReactDOM.createRoot(document.getElementById('root')!);

root.render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<App />} />
      <Route path="/popup" element={<PopupPage />} />
    </Routes>
  </BrowserRouter>
);
Enter fullscreen mode Exit fullscreen mode

☕ Enjoyed this post?

If you'd like to support my work, you can buy me a coffee — it really helps and means a lot!

ihsas01

Top comments (0)