• Townie
    AI
  • Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
peterqliu

peterqliu

staticServer

write html/css/js like a local project
Public
Like
staticServer
Home
Code
9
examples
4
README.md
USAGE.md
animations.js
index.html
index.ts
script.js
H
server.ts
utils.js
Branches
1
Pull requests
Remixes
History
Environment variables
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.
Sign up now
Code
/
Code
/
Search
https://peterqliu--bbdc3bbab0ec11f0a8800224a6c84d84.web.val.run
README.md

Val Town Static Server

A flexible, exportable static file server for Val Town that can serve HTML, JavaScript, CSS, and other text files from your project directory.

Features

  • πŸš€ 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

Quick Start

Basic Setup

import { quickStaticServer } from "./static-server.ts"; // Serves index.html at root, any .js/.css/.html files by path export default quickStaticServer();

Custom Index File

import { quickStaticServer } from "./static-server.ts"; export default quickStaticServer('/app.html');

Advanced Usage

Custom Configuration

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;

API Routes + Static Files

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(); } ] });

Single Page Application (SPA)

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;

Configuration Options

StaticServerOptions

OptionTypeDefaultDescription
indexFilestring'/index.html'File to serve at root path
notFoundHandlerfunctionBuilt-in 404Custom 404 response handler
errorHandlerfunctionBuilt-in errorCustom error response handler
mimeTypesobjectBuilt-in typesAdditional MIME type mappings
headersobject{}Headers added to all responses

Built-in MIME Types

  • .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

Project Structure

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

Examples

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

HTML Integration

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>

Error Handling

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

Best Practices

  1. File Organization: Keep related files in subdirectories
  2. Error Handling: Provide custom 404 pages for better UX
  3. Caching: Use appropriate cache headers for production
  4. Security: Don't serve sensitive files (use proper file extensions)
  5. Performance: Consider middleware for compression, logging, etc.

Migration from Basic Server

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();

Contributing

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!

HTTP
  • advanced-server.ts
    peterqliu--bb…84.web.val.run
  • basic-server.ts
    peterqliu--b3…84.web.val.run
  • server.ts
    peterqliu--68…84.web.val.run
Code
examplesREADME.mdUSAGE.mdanimations.jsindex.htmlindex.tsscript.js
H
server.ts
utils.js
FeaturesVersion controlCode intelligenceCLI
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
Β© 2025 Val Town, Inc.