How to read system images in an electron-react app
Hey guys, welcome to the Devmaesters website. In this post, I am going to guide you through the configurations needed to read system images within your Electron-React desktop application. Please follow the steps below, and feel free to leave a comment in the description if you encounter any issues. Let's get started.
Currently, most of you are getting the following error when trying to read a file (i.e., an image from a folder on your system):
"Error cannot load system resources."
This error is caused by a security feature that comes with Electron. There are two options for dealing with this error:
Option 1: Disabling App Security (Not Recommended) Disabling app security involves adding "websecurity: false" to web preferences in the main.js (entry file for your Electron app) as shown below:
mainWindow = new BrowserWindow({
...
webPreferences: {
webSecurity: false
}
}
This option disables web security and allows your React renderer process to access files (images) on your system.
Option 2: Registering a New Protocol (Recommended) The recommended option is to register a new protocol to replace the default protocol for reading files on React. Follow the steps below to register and use the new protocol:
Step 1:
Go to your Electron app's main.js file (entry file for your app) and import isDev (if not already imported) as shown below:
const isDev = require("electron-is-dev");
Step 2
Inside your createWindow function, add this function to register the new protocol:
const createWindow = () => {
if (!isDev) {
// Needs to happen before creating/loading the browser window;
// protocol is only used in prod
protocol.registerBufferProtocol(Protocol.scheme, Protocol.requestHandler);
}
///////////
}
Ensure that it is above the mainWindow configuration.
const createWindow = () => {
if (!isDev) {
// Needs to happen before creating/loading the browser window;
// protocol is only used in prod
protocol.registerBufferProtocol(Protocol.scheme, Protocol.requestHandler);
}
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
// preload: isDev
// ? path.join(app.getAppPath(), "/src/preload.js") // Loading it from the public folder for dev
// : path.join(app.getAppPath(), "/build/preload.js"), // Loading it from the build folder for production
contextIsolation: true,
nodeIntegration: true,
},
});
}
Step 3:
Add this function after the Electron app has finished initializing and is ready to create browser windows as shown below:
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on("ready", createWindow);
//add the code below
app.whenReady().then(() => {
protocol.registerFileProtocol('atom', (request, callback) => {
const filePath = url.fileURLToPath('file://' + request.url.slice('atom://'.length))
callback(filePath)
})
})
Step 4:
Finally, when you want to read a file from your system on the React frontend, prefix the part with the new atom file protocol "atom://". For example:
<img className='w-[90%] h-[100px]' src={`atom://${e.path}`} />
Conclusion: Thank you for reading, and feel free to drop a comment below if you run into any problems while following the steps in this post.