diff --git a/website/docs/guides/dynamic-assets.mdx b/website/docs/guides/dynamic-assets.mdx new file mode 100644 index 00000000..8b07e823 --- /dev/null +++ b/website/docs/guides/dynamic-assets.mdx @@ -0,0 +1,123 @@ +# Dynamic Assets + +If you want to load or generate assets for your frontend dynamically, you can achieve that using the +[AssetsHandler](../reference/options#assetshandler) option. The AssetsHandler is a generic `http.Handler` which will +be called for any non GET request on the assets server and for GET requests which can not be served from the +bundled assets because the file is not found. + +By installing a custom AssetsHandler, you can serve your own assets using a custom asset server. + +## Example + +In our example project, we will create a simple assets handler which will load files off disk: + +```go title=main.go {16-35,49} +package main + +import ( + "embed" + "fmt" + "github.com/wailsapp/wails/v2" + "github.com/wailsapp/wails/v2/pkg/options" + "net/http" + "os" + "strings" +) + +//go:embed frontend/dist +var assets embed.FS + +type FileLoader struct { + http.Handler +} + +func NewFileLoader() *FileLoader { + return &FileLoader{} +} + +func (h *FileLoader) ServeHTTP(res http.ResponseWriter, req *http.Request) { + var err error + requestedFilename := strings.TrimPrefix(req.URL.Path, "/") + println("Requesting file:", requestedFilename) + fileData, err := os.ReadFile(requestedFilename) + if err != nil { + res.WriteHeader(http.StatusBadRequest) + res.Write([]byte(fmt.Sprintf("Could not load file %s", requestedFilename))) + } + + res.Write(fileData) +} + +func main() { + // Create an instance of the app structure + app := NewApp() + + // Create application with options + err := wails.Run(&options.App{ + Title: "helloworld", + Width: 1024, + Height: 768, + Assets: assets, + BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1}, + OnStartup: app.startup, + AssetsHandler: NewFileLoader(), + Bind: []interface{}{ + app, + }, + }) + + if err != nil { + println("Error:", err) + } +} +``` + +When we run the application in dev mode using `wails dev`, we will see the following output: + +``` +DEB | [ExternalAssetHandler] Loading 'http://localhost:3001/favicon.ico' +DEB | [ExternalAssetHandler] Loading 'http://localhost:3001/favicon.ico' failed, using AssetHandler +Requesting file: favicon.ico +``` +As you can see, the assets handler is called when the default assets server is unable to serve +the `favicon.ico` file. + +If you right click the main application and select "inspect" to bring up the devtools, you can test +this feature out by typing the following into the console: + +``` +let response = await fetch('does-not-exist.txt'); +``` +This will generate an error in the devtools. We can see that the error is what we expect, returned by +our custom assets handler: + +
+
+
+
+
+
+