Assets
Vyuh assets are bundle-owned files that ship with a feature. They are used for CSS, JavaScript, images, templates, SQL snippets, migrations, and other resource files that belong beside the routes, services, tasks, and commands that use them.
An asset dir is a structured resource root, not a plain static directory. Only
files under public/ are web-accessible. Everything else is private framework
or application resource data.
Overview
The main public pieces are:
#[bundles::asset_dir]for registering a bundle asset directory.embed_silo!("path")for debug-filesystem and release-embedded assets.- Runtime serving of
public/**under/assets. collect_staticfor copying bundled public assets to a deployment directory.- Minijinja loading of private
templates/**files.
Asset dirs are part of bundle composition. A feature can register routes, templates, public CSS, and private resources as one bundle.
Vyuh itself also uses this convention for shared framework web assets. The
runtime crate owns vyuh/web/, which contains public CSS, JavaScript, images,
landing-page source, and private console templates. When the built-in console is
enabled, that directory is registered as an internal asset dir so the console can
serve /assets/css/vyuh.css, /assets/css/vyuh.<hash>.css, logos, and small helper
scripts without requiring application projects to copy them.
Directory Layout
Use convention folders inside each asset dir:
assets/
public/
dashboard/
dashboard.css
templates/
dashboard/
layouts/
base.html
sql/
reports.sql
migrations/
001_create_reports.sql
The folders have different visibility:
public/**is served over HTTP and copied bycollect_static.templates/**is loaded into Minijinja and is not public.sql/**,migrations/**, and other folders are private resources.
Public namespacing is done by folders under public/. For example,
public/dashboard/dashboard.css is served as /assets/dashboard/dashboard.css.
Registration
Register an asset dir in a bundle:
#![allow(unused)]
fn main() {
use rust_silos::{Silo, embed_silo};
use vyuh::prelude::*;
use vyuh::embed;
const ASSETS: Silo = embed_silo!("assets");
#[bundles::asset_dir]
fn assets() -> embed::Dir {
embed::Dir::new(ASSETS.clone())
}
let bundle = bundles::bundle! {
assets,
};
}
embed_silo! reads from the filesystem in debug builds and embeds the files in
release builds. That keeps local frontend iteration fast while making release
binaries self-contained.
Runtime Serving
Vyuh serves bundled public assets under /assets by default. The public/
prefix is stripped from the URL:
public/dashboard/dashboard.css -> /assets/dashboard/dashboard.css
public/images/logo.svg -> /assets/images/logo.svg
Only public/** participates in runtime serving. Requests cannot reach
templates/**, sql/**, migrations/**, or other private folders through the
asset route.
Built-in framework assets follow the same rule:
vyuh/web/public/css/vyuh.css -> /assets/css/vyuh.css
vyuh/web/public/img/vyuh-logo-transparent.png -> /assets/img/vyuh-logo-transparent.png
vyuh/web/templates/console/layout.html -> private Minijinja template
Static serving is intentionally bundle-owned. Register application assets through bundle asset dirs so public files and private templates ship through the same debug-filesystem and release-embedding machinery.
Templates
Minijinja templates are loaded from templates/**. The templates/ prefix is
stripped when the template is registered:
templates/dashboard/layouts/base.html -> dashboard/layouts/base.html
templates/dashboard/login.html -> dashboard/login.html
Template namespacing is done by folders under templates/. Public asset
namespacing is done by folders under public/. The two namespaces are
independent.
See Templates for rendering APIs, template source rules, and template failure modes.
A dashboard layout can refer to a public asset like this:
<link rel="stylesheet" href="/assets/dashboard/dashboard.css" />
Collect Static
collect_static copies all bundled public/** files to a target directory for
deployment through a CDN, reverse proxy, or dedicated static file host.
The destination path strips the public/ prefix:
public/dashboard/dashboard.css -> <output-dir>/dashboard/dashboard.css
public/images/logo.svg -> <output-dir>/images/logo.svg
collect_static does not copy templates, SQL files, migrations, or other
private resources. It copies the same public asset surface that runtime serving
exposes.
Use collect_static when the application server should not serve assets
directly in production, or when a deployment platform expects a static asset
directory.
Debug And Release Behavior
Assets registered through embed_silo! have different storage behavior by build
mode:
- Debug builds read from the source filesystem.
- Release builds serve embedded bytes from the compiled binary.
The logical asset paths stay the same in both modes. A file such as
public/dashboard/dashboard.css is addressed as /assets/dashboard/dashboard.css whether it is
read from disk during development or served from the binary in production.
Failure Modes
- Files outside
public/**are not publicly served or collected. - Missing public files return not found.
- Invalid paths and traversal attempts are rejected.
- Template names come from
templates/**; public asset names come frompublic/**. - Static files must live under registered bundle asset dirs and
public/**to be served by the runtime asset route.
Current Limitations
- Asset dirs do not have package metadata.
- Public URL namespacing is folder-based under
public/. - Private resource folders are reserved for framework and application use; they are not exposed over HTTP.