DEV Community

Tomasz Wegrzanowski
Tomasz Wegrzanowski

Posted on • Updated on

Electron Adventures: Episode 4: Image Gallery with Dynamic HTML

Electron Adventures: Episode 4: Image Gallery with Dynamic HTML

Let's do something a little more advanced with Electron - generate some HTML dynamically, and load it into the browser window.

There's no direct functionality for this, but we can use data URLs.

(I had to change all references to data URLs in code to da+ta as dev.to crashes if I use actual code; link to the actual code at the end of the post)

Load data URL into the web view

let { app, BrowserWindow } = require("electron")

let html = `
<!DOCTYPE html>
<html>
  <body>
    <h1>Welcome To The Internet!</h1>
  </body>
</html>
`

function createWindow() {
  let win = new BrowserWindow({})
  win.maximize()
  win.loadURL(`da`+`ta:text/html;charset=utf-8,${encodeURI(html)}`)
}

app.on("ready", createWindow)

app.on("window-all-closed", () => {
  app.quit()
})
Enter fullscreen mode Exit fullscreen mode

ARGV parsing

Well, we managed to pass generated HTML, but it's not doing anything interesting yet.

Let's pick a directory to display images from. The way we run Electron apps, argv starts with electron, ., so only third arg is the image directory.

let imageDir
let argv = process.argv

if (argv.length >= 3) {
  imageDir = argv[2]
} else {
  imageDir = `${__dirname}/images`
}
Enter fullscreen mode Exit fullscreen mode

For testing I included a folder with some US state flags in the repo, in images.

We can check that this part worked, by displaying it in the browser:

let html = `
<!DOCTYPE html>
<html>
  <body>
    <h1>Image Gallery - ${imageDir}</h1>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

You can run this either as:

$ npx electron . /path/to/images
$ npx electron .
Enter fullscreen mode Exit fullscreen mode

Find all images in directory

We can use fs and path to get all the images in a directory.

let fs = require("fs")
let path = require("path")

let findImages = (dir) => {
  let files = fs.readdirSync(dir)
  files.sort()
  return files
    .filter(x => /\.(png|jpg|jpeg|gif)/i.test(x))
    .map(x => path.join(dir, x))
}
Enter fullscreen mode Exit fullscreen mode

Display images

We're almost there. Let's change the HTML to display the images. Also switching it all to dark mode, as I had enough of all white screen.

let html = `
<!DOCTYPE html>
<html>
  <head>
    <style>
      body { background-color: black; color: white; }
      img { padding: 10px; }
    </style>
  </head>
  <body>
    <h1>Image Gallery</h1>
    ${ findImages(imageDir).map(x => `<img src="file://${x}" />`).join("") }
  </body>
</html>
`
Enter fullscreen mode Exit fullscreen mode

Web security

This should work but it doesn't. Let's try to figure out why.

In Electron you can go to View menu and select "Toggle Developer Tools". Or use appropriate keyboard shortcut like Cmd-Option-I. You get all the usual Chrome debugging tools!

In this case we can see that our image requests were all blocked. This makes sense. Letting data URLs load arbitrary file: URLs doesn't sound terribly safe.

As this is just a tutorial one-off, let's disable web security rules without thinking too much about the consequences of that.

function createWindow() {
  let win = new BrowserWindow({webPreferences: { webSecurity: false }})
  win.maximize()
  win.loadURL(`da` + `ta:text/html;charset=utf-8,${encodeURI(html)}`)
}
Enter fullscreen mode Exit fullscreen mode

Electron app security is a big topic. If you're writing an Electron app, and not just a PWA, you likely do it because you need access to something the browser won't let you have. And if so, you're largely leaving browser's protection, and you're now responsible for security of your app.

Result

And here's what we got:

Alt Text

All the code for the episode is here.

See you in the next episode!

Discussion (0)