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

shouser

utils

Public
Like
utils
Home
Code
2
serve-public
4
test
2
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
/
serve-public
/
README.md
Code
/
serve-public
/
README.md
Search
2/25/2025
README.md

Serving static files

It's quite common to want to serve static files from your backend server to the frontend.

Basic Usage

  1. Set up a /public folder in your project
  2. Import and route requests to servePublicFile
Create val
import { servePublicFile } from "https://esm.town/v/stevekrouse/utils@179-main/serve-public/index.ts"; export default async function(req: Request): Promise<Response> { const url = new URL(req.url); if (url.pathname === "/") { return servePublicFile("/public/index.html", import.meta.url); } else if (url.pathname.startsWith("/public")) { return servePublicFile(url.pathname, import.meta.url); } else { // normal server code here } }

Implementation

Serving files requires:

  1. Receiving requests for those files in your server
  2. Reading those files in the right place in the project
  3. Adding the correct content-type

Part (1) is handled by you in your server code.

Part (2) is handled by servePublicFile, because you give it two things:

a. The relative path of the file to serve b. The import.meta.url of the current file, so it's able to figure out the appropriate relative base path for your esm URLs. (So this will work across forks and branches!)

Part 3 is also handled by servePublicFile, because it uses an npm library to turn file extensions into content types.

TypeScript and TSX Transpilation

esm.town is able to transpile your code, so this library always does that, assuming that this code will be run on the client, which requires this transpilation.

This library also assumes that if it receives a request for script.js that in your server it might be named script.ts or script.tsx, so if it doesn't find script.js, it will try looking for the file under those other two extensions.

Get started with a template:
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.