The purpose of using the preload.js script in Electron is to provide a secure communication bridge between the renderer process (typically a web page) and the main process. This allows you to access specific Node.js functionalities while keeping nodeIntegration disabled in the renderer process (for security reasons).
1. Create the preload.js file
In your Electron application's source code, create a file named preload.js. This file will be loaded in the renderer process but executed before any web content is loaded.
2. Add logic to preload.js
In preload.js, you can use Node.js APIs to expose certain functionalities to the renderer process. For example, you might want to securely expose the ipcRenderer interface using the contextBridge API:
javascript// preload.js const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('electronAPI', { sendMessage: (channel, data) => { // Whitelist channels let validChannels = ['toMain', 'anotherChannel']; // Define a list of valid channel names if (validChannels.includes(channel)) { ipcRenderer.send(channel, data); } }, receiveMessage: (channel, func) => { let validChannels = ['fromMain', 'anotherChannel']; if (validChannels.includes(channel)) { // Deliberately strip the event as it includes `sender` ipcRenderer.on(channel, (event, ...args) => func(...args)); } } });
3. Specify preload.js in BrowserWindow
When creating a BrowserWindow, specify the path to the preload script in the webPreferences configuration and ensure nodeIntegration is disabled:
javascript// main.js const { app, BrowserWindow } = require('electron'); const path = require('path'); function createWindow() { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js'), nodeIntegration: false, contextIsolation: true // Important: This protects your application from context pollution } }); win.loadFile('index.html'); } app.whenReady().then(createWindow);
4. Use the exposed functionalities in the renderer process
Now, you can safely access the functionalities exposed by preload.js in your renderer process scripts, for example:
javascript// Renderer process script window.electronAPI.sendMessage('toMain', 'Hello, main process!'); window.electronAPI.receiveMessage('fromMain', (data) => { console.log(`Received ${data} from main process`); });
This approach enables secure communication between different parts of your Electron application while maintaining robust security practices.
Notes
- Always validate the channel names used in
preload.jsand expose only necessary IPC channels to the renderer process. - Ensure
contextIsolationis set totrueto prevent security issues that may arise when scripts run in the global context. nodeIntegrationshould remain disabled to prevent the renderer process from directly accessing Node.js APIs, which increases security risks.