Serve Static Files
Not only can you serve all your static files, but SimpleW is also great at serving your JavaScript applications — whether they're built with Vue, React, or anything else.
That's the goal of the StaticFilesModule.
Static File Resolution Flow
Incoming request path
|
v
Prefix match?
| no
v
next route / 404
yes
|
v
Map URL to file path
|
v
File exists?
| no -------------------------> 404 or auto-index
|
yes
|
v
Cache enabled?
| yes --> serve cached entry / refresh via watcher
| no --> read from disk
|
v
Range header?
| yes --> Partial Content
| no --> Full file
|
v
Response sentBasic
To serve static files with very few lines of code :
using System;
using System.Net;
using SimpleW;
using SimpleW.Modules;
namespace Sample {
class Program {
static async Task Main() {
// debug log
Log.SetSink(Log.ConsoleWriteLine, LogLevel.Debug);
// listen to all IPs port 2015
var server = new SimpleWServer(IPAddress.Any, 2015);
// use the StaticFilesModule
server.UseStaticFilesModule(options => {
options.Path = @"C:\www\spa\"; // serve your files located here
options.Prefix = "/"; // to "/" endpoint
options.CacheTimeout = TimeSpan.FromDays(1); // cached for 24h
options.AutoIndex = true; // enable autoindex if no index.html exists in the directory
});
// run server
await server.RunAsync();
}
}
}Then just point your browser to http://localhost:2015/.
Note : if AutoIndex is false and the directory does not contain a default document index.html, an http 404 error will return.
Note : on Windows, the Firewall can block this simple console app even if exposed on localhost and port > 1024. You need to allow access otherwise you will not reach the server.
Multiple Directories
SimpleW can handle multiple directories as soon as they are declared under different endpoints.
using System;
using System.Net;
using SimpleW;
using SimpleW.Observability;
using SimpleW.Modules;
namespace Sample {
class Program {
static async Task Main() {
// debug log
Log.SetSink(Log.ConsoleWriteLine, LogLevel.Debug);
// listen to all IPs port 2015
var server = new SimpleWServer(IPAddress.Any, 2015);
// serve directories/endpoints
server.UseStaticFilesModule(options => {
options.Path = @"C:\www\frontend\";
options.Prefix = "/";
options.CacheTimeout = TimeSpan.FromDays(1);
});
server.UseStaticFilesModule(options => {
options.Path = @"C:\www\public\";
options.Prefix = "/public/";
options.CacheTimeout = TimeSpan.FromDays(1);
});
await server.RunAsync();
}
}
}Options
You can change some settings before server start.
To change the default document index.html to your own page
option.DefaultDocument = "maintenance.html";Cache
By default, the StaticFilesModule() serves directories/files from disk to each request. To enable cache, set the CacheTimeout property to anything but null.
The following example enables cache for 1 day :
// serve statics files
server.UseStaticFilesModule(options => {
options.Path = @"C:\www\"; // serve your files located here
options.Prefix = "/"; // to "/" endpoint
options.CacheFilter = "*.csv"; // cache only csv files
options.CacheTimeout = TimeSpan.FromDays(1); // cached for 24h
});NOTE
When cache is enabled, an internal filesystem watcher is keeping this cache up-to-date. It supports realtime file editing even when specific lock/write occurs.
Compressed disk cache
To avoid compressing the same static file on every request without keeping its content in memory, enable the compressed disk cache:
server.UseStaticFilesModule(options => {
options.Path = @"C:\www\";
options.CompressedDiskCache = true;
});The module generates gzip and Brotli variants on demand next to the original file, then streams those variants directly from disk. The compression extension is appended to the source name: assets/app.js.br or assets/app.js.gz. Stale variants are regenerated when the source modification date changes and remain available across server restarts.
Range requests always use the original uncompressed file.
Range Requests (Streaming Support)
The StaticFilesModule automatically supports HTTP Range requests when serving files. This means that clients can request only a portion of a file instead of downloading it entirely.
This feature is particularly important for video files such as .mp4.
Modern browsers use Range requests to :
- Start playback instantly
- Jump (seek) to a specific timestamp
- Avoid downloading the full file
With SimpleW, this works out of the box :
server.UseStaticFilesModule(options => {
options.Path = @"C:\videos\";
options.Prefix = "/videos/";
});Then :
http://localhost:2015/videos/movie.mp4The video will :
- Start immediately
- Allow seeking
- Use efficient partial downloads
How to serve a Vue app
This section shows how to serve a Vue.js application.
First, create your vue/vite application :
$ npm create vite@latest my-vue-app
> npx
> create-vite my-vue-app
│
◇ Select a framework:
│ Vue
│
◇ Select a variant:
│ JavaScript
│
◇ Use rolldown-vite (Experimental)?:
│ No
│
◇ Install with npm and start now?
│ Yes
│
◇ Scaffolding project in C:\www\toto\myapp\my-vue-app...
│
◇ Installing dependencies with npm...
added 35 packages, and audited 36 packages in 5s
6 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
│
◇ Starting dev server...
> my-vue-app@0.0.0 dev
> vite
VITE v7.1.12 ready in 397 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show helpNode will create all files and start serving the application using its own built-in web server. But we want SimpleW to serve the application in production mode.
So, build the application release :
$ cd my-vue-app
$ npm run build
> my-vue-app@0.0.0 build
> vite build
vite v7.1.12 building for production...
✓ 16 modules transformed.
dist/index.html 0.46 kB │ gzip: 0.29 kB
dist/assets/index-CIkLTZfM.css 1.26 kB │ gzip: 0.64 kB
dist/assets/index-Cc-rvdMb.js 61.31 kB │ gzip: 24.69 kB
✓ built in 424msTo get the location of the dist files, run :
$ pwd
> C:\www\my-vue-app\distNow, we will serve this directory using the StaticFilesModule module of SimpleW :
using System;
using System.Net;
using SimpleW;
using SimpleW.Observability;
using SimpleW.Modules;
namespace Sample {
class Program {
static async Task Main() {
// debug log
Log.SetSink(Log.ConsoleWriteLine, LogLevel.Debug);
// listen to all IPs port 2015
var server = new SimpleWServer(IPAddress.Any, 2015);
server.UseStaticFilesModule(options => {
options.Path = @"C:\www\my-vue-app\dist\"; // serve your files located here
options.Prefix = "/"; // to "/" endpoint
options.CacheTimeout = TimeSpan.FromDays(1); // cached for 24h
options.AutoIndex = true; // enable autoindex if no index.html exists in the directory
});
// run server
await server.RunAsync();
}
}
}Open your browser to http://localhost:2015/ and you will see your vue.js app.
NOTE
You can update any files in this directory without having to reload SimpleW.