Tutorial

Serve Images, CSS, and JavaScript

Register an asset filesystem with Marionette, then reference images and custom frontend files from your pages.

Step 1

Create an Assets Directory

Create an assets/ directory for images, stylesheets, and browser-side JavaScript.

mkdir assets
touch assets/app.css
touch assets/hero.jpg

Step 2

Register the Directory

Use app.Assets with any Go fs.FS. For local development, os.DirFS("assets") is the smallest setup.

package main

import (
    "os"
    "time"

    mb "github.com/YoshihideShirai/marionette/backend"
    mf "github.com/YoshihideShirai/marionette/frontend"
)

func main() {
    app := mb.New()

    app.Assets("/assets", os.DirFS("assets"),
        mb.WithAssetCache(24*time.Hour),
    )
    app.AddStylesheet(app.Asset("app.css"))

    app.Page("/", func(ctx *mb.Context) mf.Node {
        return mf.Container(mf.ContainerProps{
            MaxWidth: "3xl",
            Centered: true,
        },
            mf.Image(mf.ImageProps{
                Src:         ctx.Asset("hero.jpg"),
                Alt:         "Dashboard preview",
                Width:       1200,
                Height:      800,
                AspectRatio: "video",
                ObjectFit:   "cover",
            }),
        )
    })

    if err := app.Run("127.0.0.1:8080"); err != nil {
        panic(err)
    }
}

Step 3

Build Asset URLs

Use app.Asset when configuring app-level stylesheets or scripts, and ctx.Asset inside handlers.

  • app.Asset("app.css") becomes /assets/app.css
  • ctx.Asset("hero.jpg") becomes /assets/hero.jpg
  • Absolute https:// URLs pass through unchanged.

Step 4

Embed Assets for Deployment

For single-binary deployment, use Go embed.FS with fs.Sub and pass the resulting filesystem to app.Assets.

package main

import (
    "embed"
    "io/fs"
    "time"

    mb "github.com/YoshihideShirai/marionette/backend"
)

//go:embed assets
var embeddedAssets embed.FS

func main() {
    app := mb.New()

    assets, err := fs.Sub(embeddedAssets, "assets")
    if err != nil {
        panic(err)
    }
    app.Assets("/assets", assets,
        mb.WithAssetCache(365*24*time.Hour),
        mb.WithAssetImmutable(),
    )

    // Register pages and actions here.
}

Step 5

What You Learned

  • Serve static files with app.Assets
  • Build URLs with app.Asset and ctx.Asset
  • Use embed.FS for deployable binaries

Next, learn how the backend communicates with the frontend.