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
This guide shows you how to import and use the static server in your own Val Town projects.
- Copy static-server.tsto your project
- Import and use:
import { 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({
  notFoundHandler: async (pathname) => {
    // For routes without extensions, serve the SPA
    if (!pathname.includes('.')) {
      return await serveFile('/index.html');
    }
    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>
- Create your HTML/JS/CSS files in your project
- Set up the server using one of the examples above
- Set the server file as HTTP trigger in Val Town
- Test your site - all files will be served automatically
- Add more files - just reference them in HTML, no server changes needed
Use the Val Town requests panel to see:
- Which files are being requested
- Response status codes
- Any error messages
- Middleware logs (if using advanced server)
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
- Your server file should be set as an HTTP trigger
- All other files (HTML, JS, CSS) are served automatically
- No build step required - files are served as-is
- Changes to files are reflected immediately
- File Organization: Use subdirectories for better organization
- Performance: Add appropriate cache headers for production
- Security: Only serve files you intend to be public
- Debugging: Use middleware for logging and monitoring
- APIs: Mix static files with dynamic API endpoints easily
Check out the /examples/ directory for working examples:
- basic-server.ts- Minimal setup
- custom-server.ts- Custom configuration
- advanced-server.ts- API routes + middleware
- spa-server.ts- Single Page Application
Each example is a complete, working server you can copy and modify!