Given:
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
sandbox: true,
}
I need to access the result of app.getPath("appData") in my renderer process.
app.getPath("appData") only works in the main process.
contextBridge.exposeInMainWorld() only works on the preload script.
How do I expose the result of app.getPath("appData") to the renderer if the preload script can't access app.getPath("appData") and the main process can't access contextBridge.exposeInMainWorld()?
You can
exposeInMainWorld to put a Promise-invoking function on the window. When invoked, make a request to the main process// Main process:
ipcMain.handle('getPath', () => app.getPath("appData"));
// Preload:
contextBridge.exposeInMainWorld('electronAPI', {
getPath: () => ipcRenderer.invoke('getPath')
});
// Renderer:
window.electronAPI.getPath()
.then((appDataPath) => {
// ...
})
.catch(handleErrors);
The preload script essentially acts as a bridge between the sandboxed page and the privileged main process - often, most of an application's logic will live either in the main process or the renderer, and the preload only bridges them.
For a more generalized approach of sending messages from the renderer to main (possibly while waiting for a response), I've found the following to work pretty well:
// Preload:
contextBridge.exposeInMainWorld('electronAPI', {
sendMessageToMainProcess: (channel: string, payload: unknown) => ipcRenderer.invoke(channel, payload),
});