The App
Static files and error pages
A Rails app serves public/404.html, public/500.html and robots.txt even in --api mode, because that happens below the router, not in a view. Bogie does the same with a public/ folder that is go:embedded into the binary, so a deployed container needs no files beside it. Since v0.2.7; index.html at / since v0.2.8.
What a new app has
public/
public.go //go:embed *.html images
404.html any request nothing answered
500.html a handler that panicked
images/ the mascot art the two pages use
How a request reaches public/
Every real route wins first. A request no route matched goes through three handlers, mounted in app/controllers/routes.go:
r.NoRoute(s.staticFile, s.welcome, s.notFound)
staticFilelooks the request path up inpublic/and, if a file is there, serves it as itself, with its content type from the extension./meanspublic/index.html.welcomeanswersGET /in development only, when nothing above did.notFoundanswers withpublic/404.htmland status 404, always.
A panicking handler gets public/500.html from middlewares.Recover, outside this chain. Edit either page freely; they are yours.
Adding a file
Drop it in public/, then widen the go:embed line in public/public.go so the binary carries it. Only what the pattern matches is embedded; anything else is a 404 even though it is on disk.
// public/public.go
//go:embed *.html *.txt *.ico css images
var Files embed.FS
With that line, public/robots.txt answers at /robots.txt, public/favicon.ico at /favicon.ico, and public/css/app.css at /css/app.css, in every environment. A directory named in the pattern brings everything under it.
A page at /
Add public/index.html (already matched by *.html) and GET / serves it in every environment, ahead of the development welcome page. A controller mounted at / still wins over both.
What it is not
- Not an asset pipeline. Files are served as they are: no compiling, no fingerprinted names.
- Not for uploads.
public/is fixed when the binary is built. Files users upload at runtime need storage of their own and a controller that serves them. - Not a CDN. Embedded files carry no modification time, so no
Last-Modifiedheader is sent; put a cache or CDN in front if the files are large or hot.
Product images and other uploads. Because public/ is fixed when the app is built, an image a user uploads, such as a product photo in a shop, cannot land there: it needs storage of its own, outside the binary. Uploads are out of the book's scope; public/ is for the files you ship with the app.
Bringing it to an older app
Commit your work, then bogie app:update: it adds public/ and app/controllers/public.go, and merges the updated routes.go, welcome.go and middlewares. See Upgrading an app.