Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(fiber): Packaged assets not being served #265

Merged
merged 1 commit into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion cmd/template/advanced/files/htmx/imports/fiber.tmpl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"github.com/a-h/templ"
"{{.ProjectName}}/cmd/web"
"github.com/gofiber/fiber/v2/middleware/adaptor"
"github.com/gofiber/fiber/v2/middleware/adaptor"
"github.com/gofiber/fiber/v2/middleware/filesystem"
"net/http"
6 changes: 5 additions & 1 deletion cmd/template/advanced/files/htmx/routes/fiber.tmpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
s.App.Static("/assets", "./cmd/web/assets")
s.App.Use("/assets", filesystem.New(filesystem.Config{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you don't have to use FS. The issue is with your OS/machine package. The asset (static files) is not being served because FS already has the magic embedded here:

package web

import "embed"

//go:embed "assets"
var Files embed.FS

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into it.

Although we are declaring the embed.FS variable Files, this is not actually being referred to in the original s.App.Static() method. So, I believe the method was looking in the actual file system instead. This makes sense because it was working fine on my local development environment. But once I built it and ran the binary in an isolated environment, I ran into the issue of the assets not being there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into it.

Although we are declaring the embed.FS variable Files, this is not actually being referred to in the original s.App.Static() method. So, I believe the method was looking in the actual file system instead. This makes sense because it was working fine on my local development environment. But once I built it and ran the binary in an isolated environment, I ran into the issue of the assets not being there.

It's because the path/directory is different.

Here's an example of how to use static files with magic embedding:

The static.go file is located in the frontend/public directory:

package frontend

import "embed"

// Files is an embedded file system containing the static files from the "images" directory.
//
// Note: This is a "magic embedded" line and should not be removed, as it is initialized before other code (even another FS System).
//
//go:embed "assets/images"
var Files embed.FS

Then, in Fiber, you can call it like this:

	app.Static("/styles/", "./frontend/public/assets", fiber.Static{
		Compress: true,
		// Note: It's important to disable this when using middleware cache to avoid confusion,
		// as caching is already handled by the middleware cache.
		CacheDuration: -1 * time.Microsecond,
	})

It works well for me on Linux, Windows, and Unix systems without using a file system such as the Fiber file manager (e.g., filesystem.New()).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I found in the official Fiber docs.

// Embed a single file
//go:embed index.html
var f embed.FS

// Embed a directory
//go:embed static/*
var embedDirStatic embed.FS

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

	app.Use("/", filesystem.New(filesystem.Config{
		Root: http.FS(f),
	}))

	// Access file "image.png" under `static/` directory via URL: `http://<server>/static/image.png`.
	// Without `PathPrefix`, you have to access it via URL:
	// `http://<server>/static/static/image.png`.
	app.Use("/static", filesystem.New(filesystem.Config{
		Root: http.FS(embedDirStatic),
		PathPrefix: "static",
		Browse: true,
	}))

	log.Fatal(app.Listen(":3000"))
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I found in the official Fiber docs.

// Embed a single file
//go:embed index.html
var f embed.FS

// Embed a directory
//go:embed static/*
var embedDirStatic embed.FS

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

	app.Use("/", filesystem.New(filesystem.Config{
		Root: http.FS(f),
	}))

	// Access file "image.png" under `static/` directory via URL: `http://<server>/static/image.png`.
	// Without `PathPrefix`, you have to access it via URL:
	// `http://<server>/static/static/image.png`.
	app.Use("/static", filesystem.New(filesystem.Config{
		Root: http.FS(embedDirStatic),
		PathPrefix: "static",
		Browse: true,
	}))

	log.Fatal(app.Listen(":3000"))
}

@mubashiroliyantakath The alternative without using the filesystem middleware works. The only thing you need to do is put the magic embed before the other Go code. Here's an example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and I've been using it in my template.

Root: http.FS(web.Files),
PathPrefix: "assets",
Browse: false,
}))

s.App.Get("/web", adaptor.HTTPHandler(templ.Handler(web.HelloForm())))

Expand Down