title: Electron IpcRendrer not sending data from Main to HTML
body: <p>I'm creating a WhatsApp client similar to WhatsAppWeb. I use IPC for communication between HTML and main using the following preload.js</p>
  <pre><code>const { ipcRenderer, contextBridge } = require(&quot;electron&quot;);
  
  
  contextBridge.exposeInMainWorld(&quot;api&quot;, {
      send: (channel, data) =&gt; {
          // whitelist channels
          let validChannels = [&quot;toMain&quot;];
          if (validChannels.includes(channel)) {
              ipcRenderer.send(channel, data);
          }
      },
      receive: (channel, func) =&gt; {
          let validChannels = [&quot;fromMain&quot;];
          if (validChannels.includes(channel)) {
              ipcRenderer.on(channel, (_, ...args) =&gt; func(...args));
          }
      }
  });
  </code></pre>
  <p>the following is main.js</p>
  <pre><code>const path = require(&quot;path&quot;);
  const client = require(&quot;./src/client&quot;).instance;
  const { app, ipcMain, BrowserWindow } = require(&quot;electron&quot;);
  
  let win;
  function createWindow() {
      win = new BrowserWindow({
          width: 1280,
          height: 800,
          icon: path.join(__dirname, &quot;views&quot;, &quot;images&quot;, &quot;logo.png&quot;),
          webPreferences: {
              nodeIntegration: false,
              contextIsolation: true,
              enableRemoteModule: false,
              preload: path.join(__dirname, &quot;src&quot;, &quot;preload.js&quot;),
          }
      });
  
      win.maximize();
      win.loadFile(path.join(&quot;views&quot;, &quot;login.html&quot;));
      win.webContents.openDevTools();
  }
  
  app.whenReady().then(() =&gt; {
      createWindow();
  
      app.on(&quot;activate&quot;, () =&gt; {
          if (BrowserWindow.getAllWindows().length === 0)
              createWindow();
      });
  });
  
  app.on(&quot;window-all-closed&quot;, () =&gt; {
      if (process.platform !== &quot;darwin&quot;)
          app.quit();
  });
  
  client.addListner(&quot;qr&quot;, (url) =&gt; {
      // this works fine and logging the URL after page change using a console log prints a valid qrcode url
      if (!client.isReady()) {
          let logoFilePath = path.join(__dirname, &quot;views&quot;, &quot;images&quot;, &quot;logo.png&quot;);
          win.webContents.send(&quot;fromMain&quot;, {
              event: &quot;onQr&quot;,
              args: {
                  url: url,
                  logoFilePath: logoFilePath
              }
          });
      }
  });
  
  client.login();
  
  ipcMain.on(&quot;toMain&quot;, (_, data) =&gt; {
      let { event, args } = data;
      switch (event) {
          case &quot;logout&quot;:
              client.logout().then(() =&gt; client.login());
          default:
              break;
      }
  });
  </code></pre>
  <p>I have 2 HTML pages login.html and index.html the following are screenshots to explain the sequence of the application.
  <a href="https://i.stack.imgur.com/BdYCF.png" rel="nofollow noreferrer">screenshot of login.html</a>
  the following is the script tag in login.html that interacts with the main process.</p>
  <pre><code>&lt;script&gt;
      window.api.receive(&quot;fromMain&quot;, (data) =&gt; {
          let { event, args } = data;
          switch (event) {
              case &quot;onQr&quot;:
                  generateQrCode(args.url, args.logoFilePath);
                  break;
              case &quot;onReady&quot;:
                  window.location.replace(&quot;index.html&quot;);
                  break;
              default:
                  break;
          };
      });
  &lt;/script&gt;
  </code></pre>
  <p><a href="https://i.stack.imgur.com/Lyh1N.png" rel="nofollow noreferrer">screenshot of index.html</a>
  the following is the script tag receiving and sending to the main process in login.html</p>
  <pre><code>$(&quot;#logoutBtn&quot;).click((event) =&gt; {
      event.preventDefault();
      window.api.send(&quot;toMain&quot;, {
          event: &quot;logout&quot;,
          args: {}
      });
      // I think the problem may be here on page redirection becuase
         it almost feels like the script doesn't run at all in login.html after being reloaded
      window.location.replace(&quot;login.html&quot;);
  });
  </code></pre>
  <p>after pressing the logout button the login page is loaded normally and the backend process generates a qr code normally but the recieve function is never triggered again.
  trying to check if send function is the main process is working by adding a console log in the preload recieve function gives the following result in the console.</p>
  <pre><code>// preload after modification
  const { ipcRenderer, contextBridge } = require(&quot;electron&quot;);
  
  
  contextBridge.exposeInMainWorld(&quot;api&quot;, {
      send: (channel, data) =&gt; {
          // whitelist channels
          let validChannels = [&quot;toMain&quot;];
          if (validChannels.includes(channel)) {
              ipcRenderer.send(channel, data);
          }
      },
      receive: (channel, func) =&gt; {
          let validChannels = [&quot;fromMain&quot;];
          if (validChannels.includes(channel)) {
              // the console logs works fine
              console.log(&quot;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; recieving&quot;);
              console.log(func);
              // this line doesn't do anything in the second page load
              ipcRenderer.on(channel, (_, ...args) =&gt; {
                  func(...args);
              });
          }
      }
  });
  </code></pre>
  <p><a href="https://i.stack.imgur.com/LZ7DJ.png" rel="nofollow noreferrer">screenshot of console logs in login.html</a>
  what I'm trying to achieve is that login loads again after logout the application sequence starts over however the login page doesn't recieve anything from the main process after being reloaded even though the recieve function was triggered successfully which leads me to suspect the problem is in the way I reload the page using window.location.replace</p>