FBSdeveloper
FBSdeveloper

Reputation: 1

Electron-React-Boilerplate 4.0: Property 'electron' does not exist on type 'Window & typeof globalThis'. Did you mean 'Electron'?

I am trying to call the IPCrenderer through the built-in context bridge and receive the following error:

Property 'electron' does not exist on type 'Window & typeof globalThis'. Did you mean 'Electron'?

I have added tailwind CSS but can not imagine that is causing the issue here. Below is my code.

App.tsx

import { MemoryRouter as Router, Switch, Route } from 'react-router-dom';
import './App.global.css';

const Login = () => {
  const handleButtonClick = () => {
    window.electron.ipcRenderer.onButtonClick('Button Clicked');
  };

  return (
    <div>
      <button
        type="button"
        onClick={handleButtonClick}
        className="bg-black text-white p-2 font-bold rounded-xl shadow-xl outline-none hover:bg-gray-500 transform hover:scale-110"
      >
        Login &gt;
      </button>
    </div>
  );
};

export default function App() {
  return (
    <Router>
      <Switch>
        <Route path="/" component={Login} />
      </Switch>
    </Router>
  );
}

main.tsx (code snippet added in event listener section)

ipcMain.on('button-example', (arg) => {
  console.log(arg);
});

preload.js

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electron', {
  ipcRenderer: {
    onButtonClick() {
      ipcRenderer.send('button-example', 'Button Clicked');
    },
  },
});

Any guidance on this topic would be helpful.

Upvotes: 0

Views: 1765

Answers (3)

Samuel G. P.
Samuel G. P.

Reputation: 3074

You should use a custom name like electronApi instead of electron or ipcRenderer when exposing custom methods to the main world:

preload.js

contextBridge.exposeInMainWorld('electronAPI', {
  onButtonClick: () => ipcRenderer.send('button-example', 'Button Clicked'),
})

Use it in the web renderer like so:

App.tsx

const handleButtonClick = () => {
  window.electronApi.onButtonClick('Button Clicked');
};

To suppress the warnings about the method name you can create an interface.d.ts inside the electron directory and declare the method signatures in it:

electron/interface.d.ts

export interface IElectronAPI {
  onButtonClick: () => void
}

declare global {
  interface Window {
    electronAPI: IElectronAPI
  }
}

It worked for me. I hope it works for you.

Reference: https://www.electronjs.org/pt/docs/latest/tutorial/context-isolation

Upvotes: 0

Gabriel Cobos
Gabriel Cobos

Reputation: 35

You could add an index.d.ts file to your project's root directory/src folder, and supply your type interfaces there.

Example:

/src/index.d.ts

export {}

declare global {
  interface InterfaceName {
    someProperty: any
  }

  ...
}

Upvotes: 0

Guest
Guest

Reputation: 51

@FBSdeveloper,

I had the same issue too. After I searched the internet, I came up with this solution:-

Edit your index.tsx from something like this:-

import { render } from "react-dom";
import App from "./App";


render(<App />, document.getElementById("root"));

to something like this:-

import { render } from "react-dom";
import App from "./App";

declare global {
  interface Window {
    electron: any;
  }
}

render(<App />, document.getElementById("root"));

Now you can use window.electron anywhere in the renderer. This fixed the problem for me. You could also add this in the App.js file.

Although I have not tested it, you can do something like this too:-

preload.js

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electron', {
  hworld: "Hello world" // window.electron.hworld is a string ("Hello world")
});

index.tsx

import { render } from "react-dom";
import App from "./App";

declare global {
  interface Window {
    electron: {
      hworld: string // Since you know window.electron.hworld is a string
    }
  }
}

render(<App />, document.getElementById("root"));

Upvotes: 5

Related Questions