@left Inertia’s more for bridging the gap between a server-rendered app and a SPA. There is no “server” in an Electron app because the Electron app is running on the user’s device. Therefore it makes more sense just to build the Electron app using Vue and JavaScript.
Can I make Inertia.js + Electron App
Is it possible to create Electron desktop app using Laravel + Inertia.js?
Thank you for your answer! What if I want to have all good things provided by Laravel, such us routing, guards, middleware, form validation and so on. Why would i build those obvious components by myself from scratch if there is already a very good solution to that. I was hoping to build an SPA like - desktop app, with Laravel as a provider of all the necessary components listed above.
What if I want to have all good things provided by Laravel, such us routing, guards, middleware, form validation and so on.
@Left Laravel is written in PHP. PHP is a server-side language. It runs on a web server. Electron apps don‘t run on a web server. They run on people’s computers.
I was hoping to build an SPA like - desktop app, with Laravel as a provider of all the necessary components listed above.
Which is what you would do. The Electron app would be the SPA, and can then communicate with a Laravel API. But there wouldn’t be any Laravel inside the Electron app itself. It’s a client. Not a full stack web app.
What if point my Electron App entry point to the Laravel + Inertia.js App hosted on the server and simply use it like this? Client can then install my app on his desktop and have fully functional app. Correct me if I'm wrong.
I don't want to serve this app over the Internet to be open for everyone, so i thought i can make Electron desktop app to be let's say "a pointer" to my Inertia + Laravel App, then only users who installed the app can have access to it.
What if point my Electron App entry point to the Laravel + Inertia.js App hosted on the server and simply use it like this?
@left That makes no sense. Electron is for building self-contained apps that people run on their computers. Not for framing a website. If you want to build a website, build a website.
@Left also is it going to be a single computer usage or a client server setup like you would do when visual foxpro was used or like Access can be used in a client server setup?
Does it need laravel or would programming what's needed in Libreoffice base or MS Access be a better fit?
Just curious.
@left It seems no one answering here has any clue what Electron is or how it works.
Of course it's possible and it isn't that of a stupid idea. Let me explain. I just recovered this account I never used to answer your question, because your question is a valid question and deserves a decent answer.
Electron boots basically three files, the main.js, preload.js and a .html file as an entry point for the chrome frontend. The main.js runs in the main process, the preload.js and any .html runs in the renderer process. This basically means that anything running in the renderer process could access electrons API. You just have to write it and make it available using the ContextBridge, ipcMain and the ipcRenderer.
So first off, you need an entry point to your website, e.g. web-app. I'll just use the default electrons example index.html and add a redirect in the header. This redirect will be your app on some domain/server somewhere.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="2;url=https://someapponyourserver.com" />
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
</body>
</html>
This is a simplified version of the main.js booting the process, creating a window, loading the preload.js and using ipcMain to register a handler for opening a dialog.
const { ipcMain, dialog, app, BrowserWindow } = require('electron')
const path = require('path')
// open dialog
ipcMain.handle('dialog', async (event, method, params) => {
return await dialog[method](params);
});
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
mainWindow.webContents.openDevTools();
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
The preload is able to "expose" any handlers into the real world, e.g. the "window" object.
const { contextBridge, ipcRenderer, BrowserWindow } = require('electron')
contextBridge.exposeInMainWorld('electron', {
test: "hello from electron",
openDialog: (method, config) => ipcRenderer.invoke('dialog', method, config)
});
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
Now anywhere in your app, you can do something simple as the following:
if(window.electron) {
alert(window.electron.test);
// will alert "hello from electron" as defined in the contextBridge.exposeInMainWorld('electron', ... )
}
or opening a window doing the following
if(window.electron) {
await electron.openDialog("showOpenDialogSync", {
title: "Select a file",
buttonLabel: "This one will do",
properties: ["openFile"],
}).then(function(canceled, paths) {
console.log(canceled);
console.log(paths)
});
}
It's basically just as simple as that. The only part is to write a clean API to distinguish when running a browser and when in electron (which is a browser all the same, just chrome).
@dbf Cool. Let me know how your Electron app functions offline if you’re just going to essentially iframe a website.
Please or to participate in this conversation.