A flexible, exportable static file server for Val Town that can serve HTML, JavaScript, CSS, and other text files from your project directory.
import { quickStaticServer } from "./static-server.ts";
// Serves index.html at root, any .js/.css/.html files by path
export default quickStaticServer();
import { quickStaticServer } from "./static-server.ts";
export default quickStaticServer('/app.html');
import { createStaticServer } from "./static-server.ts";
const { handler } = createStaticServer({
indexFile: '/index.html',
headers: {
'Cache-Control': 'no-cache',
'X-Powered-By': 'My App'
},
mimeTypes: {
'.ts': 'text/typescript; charset=utf-8'
},
notFoundHandler: (pathname) => {
return new Response(`Custom 404: ${pathname} not found`, {
status: 404,
headers: { 'Content-Type': 'text/plain' }
});
}
});
export default handler;
import { advancedStaticServer } from "./static-server.ts";
export default advancedStaticServer({
routes: {
'/api/health': () => new Response('OK'),
'/api/data': () => new Response(JSON.stringify({
message: 'Hello from API!'
}), {
headers: { 'Content-Type': 'application/json' }
})
},
middleware: [
async (req, next) => {
console.log(`${req.method} ${new URL(req.url).pathname}`);
return await next();
}
]
});
import { createStaticServer } from "./static-server.ts";
const { handler, serveFile } = createStaticServer({
importMetaUrl: import.meta.url, // Required!
notFoundHandler: async (pathname) => {
// Serve index.html for routes without file extensions
if (!pathname.includes('.')) {
return await serveFile('/index.html', { importMetaUrl: import.meta.url });
}
return new Response('File not found', { status: 404 });
}
});
export default handler;
| Option | Type | Default | Description |
|---|---|---|---|
indexFile | string | '/index.html' | File to serve at root path |
notFoundHandler | function | Built-in 404 | Custom 404 response handler |
errorHandler | function | Built-in error | Custom error response handler |
mimeTypes | object | Built-in types | Additional MIME type mappings |
headers | object | {} | Headers added to all responses |
.html ā text/html; charset=utf-8.js ā application/javascript; charset=utf-8.css ā text/css; charset=utf-8.json ā application/json; charset=utf-8.txt ā text/plain; charset=utf-8.md ā text/markdown; charset=utf-8.xml ā application/xml; charset=utf-8.svg ā image/svg+xml; charset=utf-8your-project/
āāā index.html # Main HTML file
āāā script.js # JavaScript files
āāā style.css # CSS files
āāā static-server.ts # The server module
āāā server.ts # Your HTTP val
āāā api/
āāā data.json # Static data files
See the /examples/ directory for complete working examples:
basic-server.ts - Minimal setupcustom-server.ts - Custom configurationadvanced-server.ts - API routes + middlewarespa-server.ts - Single Page ApplicationYour HTML files can reference any JavaScript or CSS files:
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="/styles/main.css"> <link rel="stylesheet" href="/components/header.css"> </head> <body> <div id="app"></div> <!-- All these JS files will be served automatically --> <script src="/utils/helpers.js"></script> <script src="/components/header.js"></script> <script src="/app.js"></script> </body> </html>
The server provides helpful error messages:
"JavaScript file not found: /missing.js""Server error: [error message]"If you have an existing basic server, migration is simple:
// Before
export default async function(req: Request) {
// manual file serving logic
}
// After
import { quickStaticServer } from "./static-server.ts";
export default quickStaticServer();
This server module is designed to be:
Feel free to extend it for your specific needs!