This guide shows you how to import and use the static server in your own Val Town projects.
static-server.ts to your projectimport { quickStaticServer } from "./static-server.ts";
export default quickStaticServer();
import { quickStaticServer } from "https://esm.town/v/[username]/[project]/static-server";
export default quickStaticServer();
Create this file structure in your Val Town project:
your-project/
āāā static-server.ts # Copy this file
āāā server.ts # Your HTTP val (imports static-server)
āāā index.html # Your main HTML file
āāā script.js # JavaScript files
āāā style.css # CSS files
āāā assets/
āāā utils.js
āāā components.js
File: server.ts
import { quickStaticServer } from "./static-server.ts";
// Serves index.html at root, all other files by path
export default quickStaticServer();
Set this file as an HTTP trigger and you're done!
File: server.ts
import { createStaticServer } from "./static-server.ts";
const { handler } = createStaticServer({
indexFile: '/app.html',
headers: {
'Cache-Control': 'max-age=3600',
'X-Powered-By': 'My Static Server'
},
mimeTypes: {
'.ts': 'text/typescript; charset=utf-8'
}
});
export default handler;
File: server.ts
import { advancedStaticServer } from "./static-server.ts";
export default advancedStaticServer({
routes: {
'/api/users': async () => {
// Your API logic here
return new Response(JSON.stringify([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]), {
headers: { 'Content-Type': 'application/json' }
});
},
'/api/health': () => new Response('OK')
},
staticOptions: {
indexFile: '/index.html'
}
});
File: server.ts
import { createStaticServer } from "./static-server.ts";
const { handler, serveFile } = createStaticServer({
importMetaUrl: import.meta.url, // Required!
notFoundHandler: async (pathname) => {
// For routes without extensions, serve the SPA
if (!pathname.includes('.')) {
return await serveFile('/index.html', { importMetaUrl: import.meta.url });
}
return new Response('File not found', { status: 404 });
}
});
export default handler;
// Default index file
quickStaticServer()
// Custom index file
quickStaticServer('/app.html')
createStaticServer({
indexFile: '/index.html', // File served at root
headers: { // Headers for all responses
'Cache-Control': 'no-cache'
},
mimeTypes: { // Custom MIME types
'.vue': 'text/vue; charset=utf-8'
},
notFoundHandler: (pathname) => { // Custom 404 handler
return new Response(`Not found: ${pathname}`, { status: 404 });
},
errorHandler: (error, pathname) => { // Custom error handler
return new Response(`Error: ${error.message}`, { status: 500 });
}
})
Your HTML files can reference any JS/CSS files:
File: index.html
<!DOCTYPE html> <html> <head> <title>My App</title> <link rel="stylesheet" href="/style.css"> <link rel="stylesheet" href="/components/header.css"> </head> <body> <div id="app">Loading...</div> <!-- All these will be served automatically --> <script src="/utils/helpers.js"></script> <script src="/components/header.js"></script> <script src="/app.js"></script> </body> </html>
Use the Val Town requests panel to see:
404 Errors: Make sure file paths in HTML match actual file locations
<!-- If your file is at /assets/script.js --> <script src="/assets/script.js"></script>
MIME Type Issues: Add custom MIME types if needed
mimeTypes: {
'.ts': 'text/typescript; charset=utf-8'
}
SPA Routing: Use the SPA example for client-side routing
Check out the /examples/ directory for working examples:
basic-server.ts - Minimal setupcustom-server.ts - Custom configurationadvanced-server.ts - API routes + middlewarespa-server.ts - Single Page ApplicationEach example is a complete, working server you can copy and modify!