Public
Like
staticServer
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data β all from the browser, and deployed in milliseconds.
Viewing readonly version of main branch: v24View latest version
A flexible, exportable static file server for Val Town that can serve HTML, JavaScript, CSS, and other text files from your project directory.
- π Zero configuration - Works out of the box
- π Dynamic file serving - No hardcoded file paths
- π― Proper MIME types - Automatic content-type detection
- π§ Highly configurable - Custom options for advanced use cases
- π£οΈ API routes - Mix static files with dynamic endpoints
- π Middleware support - Add logging, auth, or custom processing
- π± SPA support - Built-in Single Page Application routing
- β Smart 404 handling - Customizable error responses
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({
  notFoundHandler: async (pathname) => {
    // Serve index.html for routes without file extensions
    if (!pathname.includes('.')) {
      return await serveFile('/index.html');
    }
    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-8
your-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 setup
- custom-server.ts- Custom configuration
- advanced-server.ts- API routes + middleware
- spa-server.ts- Single Page Application
Your 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:
- 404 for missing files: "JavaScript file not found: /missing.js"
- 500 for server errors: "Server error: [error message]"
- Custom handlers: Override with your own error responses
- File Organization: Keep related files in subdirectories
- Error Handling: Provide custom 404 pages for better UX
- Caching: Use appropriate cache headers for production
- Security: Don't serve sensitive files (use proper file extensions)
- Performance: Consider middleware for compression, logging, etc.
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:
- Extensible - Easy to add new features
- Maintainable - Clear separation of concerns
- Reusable - Works across different Val Town projects
Feel free to extend it for your specific needs!