Volga
Home
API Docs
GitHub
  • English
  • Русский
Home
API Docs
GitHub
  • English
  • Русский
  • Home
  • Basics

    • Quick Start
    • Route Parameters
    • Query Parameters
    • Route Groups
    • Headers
  • Data Formats

    • Handling JSON
    • Handling Form Data
    • Working with Files
    • Server-Sent Events (SSE)
  • Protocols

    • HTTP/1 and HTTP/2
    • HTTPS
    • WebSockets & WebTransport
  • Advanced

    • Custom Middleware
    • Response Compression
    • Request Decompression
    • Global Error Handling
    • Dependency Injection
    • Tracing & Logging
    • Static Files
    • CORS (Cross-Origin Resource Sharing)
    • Cookies
    • Request cancellation
    • Custom Handling of HEAD, OPTIONS, and TRACE Methods

Static Files

Volga supports serving static files with features such as directory browsing, a configurable index file name, path prefixing, a content root folder, and a special fallback file.

Prerequisites

Dependencies

If you're not using the full feature set, you need to enable the static-files feature in your Cargo.toml:

[dependencies]
volga = { version = "0.5.2", features = ["static-files"] }

Folder Structure

Let's assume we have the following folder structure:

project/
│── static/
│   ├── index.html
│   ├── style.css
│   ├── script.js
│── src/
│   ├── main.rs
│── Cargo.toml

Basic Static File Server

After creating html, css, and js files, you can set up a minimal static file server in main.rs:

use volga::App;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new()
        .with_host_env(|env| env.with_content_root("/static"));

    // Enables routing to static files
    app.map_static_assets();

    app.run().await
}

By default, the content root folder is set to the project root (project/). Calling with_content_root("/static") reconfigures it to project/static/.

Next, calling map_static_assets() automatically maps all necessary GET and HEAD routes:

  • / → /index.html
  • /{path} → /any_file_or_folder_in_the_root

If you have subfolders inside the content root, routes to their contents will also be mapped.

Fallback

To serve a custom fallback file (e.g., 404.html), use map_fallback_to_file(), which internally calls map_fallback() to handle unknown paths.

use volga::App;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new()
        .with_host_env(|env| env
            .with_content_root("/static")
            .with_fallback_file("404.html"));

    // Enables routing to static files
    app.map_static_assets();

    // Enables fallback to 404.html
    app.map_fallback_to_file();

    app.run().await
}

Since fallback files are disabled by default, we explicitly set the 404.html file using with_fallback_file("404.html").

A more concise version of the above code is:

use volga::App;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new()
        .with_host_env(|env| env
            .with_content_root("/static")
            .with_fallback_file("404.html"));

    // Enables routing to static files 
    // and fallback to 404.html
    app.use_static_files();

    app.run().await
}

The use_static_files() method combines map_static_assets() and map_fallback_to_file(). However, the fallback feature is only enabled if a fallback file is specified.

Tips

You can set with_fallback_file("index.html") to always redirect to the main page for unknown routes.

Directory Browsing

Like fallback files, directory browsing is disabled by default. You can enable it using with_files_listing(). However, this is not recommended for production environments.

use volga::App;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new()
        .with_host_env(|env| env
            .with_content_root("/static")
            .with_fallback_file("404.html")
            .with_files_listing());

    // Enables routing to static files 
    // and fallback to 404.html
    app.use_static_files();

    app.run().await
}

Host Environment

For more advanced scenarios, you can use the HostEnv struct, which represents the application's host environment. Using HostEnv directly makes it easier to switch between environments.

Here’s how you can achieve the same configuration with HostEnv:

use volga::{App, File, app::HostEnv};

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let env = HostEnv::new("/static")
        .with_fallback_file("404.html")
        .with_files_listing();

    let mut app = App::new()
        .set_host_env(env);

    // Enables routing to static files 
    // and fallback to 404.html
    app.use_static_files();

    // Handles new static file uploads
    app.map_post("/upload", |file: File, env: HostEnv| async move {
        let root = env.content_root();
        file.save(root).await
    });

    app.run().await
}

Additionally, HostEnv can be extracted in middlewares and request handlers.

For a full example, see this repository.

Last Updated:
Prev
Tracing & Logging
Next
CORS (Cross-Origin Resource Sharing)