Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serving static files in Electron (React app)

I am working on a project where I need to build a desktop app in Electron. The majority of functionality will be built in React, but there will be a part where we need to integrate a 3rd party static HTML magazine. I need some advice on how to do this. I am building a proof of concept app currently and I have based it on this https://github.com/chentsulin/electron-react-boilerplate

how would I add that on /static/ I server static HTML files. I know I could do it in express, but I really don't want to include the entire express framework just for serving static files.

I was looking at this https://www.npmjs.com/package/serve-static but have no Idea how to integrate it in my react app and bundle it into electron app.

like image 544
Ales Maticic Avatar asked Jul 05 '16 13:07

Ales Maticic


People also ask

How do I run a react app on electron?

Now we are ready to install Electron, open up the terminal, and run: Now, let’s add an entry to the scripts section in the package.json file to run the react app on Electron. Add electron-dev as an entry holding the value electron . under the scripts section in the package.json file as shown below.

How do I serve static content in electron?

Normally, if you run React app as a normal website, all static contents should be served by HTTP [GET]method. Though they use relative paths, your HTTP server will handle the path parsing work. However, when running under Electron, things change.

Which method is used to serve static content in react?

Explaination: Normally, if you run React app as a normal website, all static contents should be served by HTTP [GET]method. Though they use relative paths, your HTTP server will handle the path parsing work. However, when running under Electron, things change.

How do I load a file URL in electron?

Normally you would just use win.loadURL ('file://…'), but that doesn't work when you're making a single-page web app, which most Electron apps are today, as history.pushState () 'ed URLs don't exist on disk. It serves files if they exist, and falls back to index.html if not, which means you can use router modules like react-router, vue-router, etc.


1 Answers

I found another solution without using express or serve-static, we only need to cusomize Electron built-in interceptFileProtocol() to serve static contents.

Code:(main.js)

(I use the electron-quick-start as Electron template)

function createWindow () {
  window = new BrowserWindow({ width: 800, height: 600 })
  window.loadURL(url.format({
    pathname: 'index.html',    /* Attention here: origin is path.join(__dirname, 'index.html') */
    protocol: 'file',
    slashes: true
  }))

  window.on('closed', () => {
    window = null
  })
}

app.on('ready', () => {
  protocol.interceptFileProtocol('file', (request, callback) => {
    const url = request.url.substr(7)    /* all urls start with 'file://' */
    callback({ path: path.normalize(`${__dirname}/${url}`)})
  }, (err) => {
    if (err) console.error('Failed to register protocol')
  })
  createWindow()
})

Reference: protocol.interceptFileProtocol()

Explaination:

  • Normally, if you run React app as a normal website, all static contents should be served by HTTP [GET] method. Though they use relative paths, your HTTP server will handle the path parsing work.

  • However, when running under Electron, things change.

  • Your static contents usually use relative path like ./picture.jpg, Electron will use file protocol instead of HTTP protocol and find the file under root path like C://.//. So static contents like ./picture.jpg won't be loaded correctly.

  • By customizing interceptFileProtocol(), all static contents' requests will be pointed to your working directory instead of Windows(or other OS) root.

Finally, I'm not sure whether it's a good solution for all Electron projects, but if you already have a React project (or some other SPA) and want to wrap it with Electron, this solution would be fine to use.

like image 87
yeze322 Avatar answered Oct 18 '22 23:10

yeze322