Skip to content

Bundling resources

An app that loads its images from files next to the executable breaks as soon as it is moved, packaged for a phone or served on the web. Compiling the files into the executable avoids that. bellui bundle writes a Go file that embeds each file and exposes it as a bellui.StaticResource, which you can pass anywhere Bellui takes a resource: icons, images, fonts, themes.

Generating the file

bellui bundle -o bundled.go logo.svg
bellui bundle -o bundled.go -a welcome.txt

The first command creates bundled.go; -a (append) adds to it without writing the header again. Each resource gets a variable named from the resource prefix and the file name. The result for these two files:

// auto-generated
// Code generated by '$ bellui bundle'. DO NOT EDIT.

package main

import (
	_ "embed"

	"github.com/belluikit/bellui"
)

//go:embed logo.svg
var resourceLogoSvgData []byte
var resourceLogoSvg = &bellui.StaticResource{
	StaticName:    "logo.svg",
	StaticContent: resourceLogoSvgData,
}

//go:embed welcome.txt
var resourceWelcomeTxtData []byte
var resourceWelcomeTxt = &bellui.StaticResource{
	StaticName:    "welcome.txt",
	StaticContent: resourceWelcomeTxtData,
}

The generated code uses Go’s //go:embed, so the files must stay in the package folder; bellui bundle does not copy their contents into the Go file.

FlagMeaning
-o fileWrite to this file instead of standard output.
-aAppend to an existing file, without a header.
--nameThe variable name, for a single file.
--prefixThe prefix for generated names. The default is resource.
--packageThe package name in the header. The default is main.

Given a folder instead of files, bellui bundle bundles every file in it except .go files.

Regenerating with go generate

Put the commands in //go:generate lines so that go generate rebuilds the file when the assets change:

// Uses the resources that "bellui bundle" generated in bundled.go.
package main

//go:generate bellui bundle -o bundled.go logo.svg
//go:generate bellui bundle -o bundled.go -a welcome.txt

import (
	"github.com/belluikit/bellui"
	"github.com/belluikit/bellui/app"
	"github.com/belluikit/bellui/container"
	"github.com/belluikit/bellui/widget"
)

func main() {
	a := app.New()
	w := a.NewWindow("Bundled resources")

	a.SetIcon(resourceLogoSvg) // a bellui.Resource, like any other
	logo := widget.NewIcon(resourceLogoSvg)
	text := widget.NewLabel(string(resourceWelcomeTxt.Content()))

	w.SetContent(container.NewVBox(logo, text))
	bellui.ShowAndRun(w)
}

Using a resource

a.SetIcon(resourceLogoSvg) // a bellui.Resource, like any other
logo := widget.NewIcon(resourceLogoSvg)
text := widget.NewLabel(string(resourceWelcomeTxt.Content()))

Content() returns the bytes and Name() the original file name. For your own embedded files you can also call bellui.NewStaticResource directly; bellui bundle only saves you writing that code.