Repository: honojs/examples
Pull request #226: Add missing serve-static example and update README
Author: login: erik-beus
Created: 2025-02-04T12:12:51Z | Merged: 2025-03-04T07:37:16Z

The link from the README to the `serve-static` example was not working since the example didn't exist.
This change adds a new example based on the latest documentation from Hono.


Diff:
diff --git a/README.md b/README.md
index 3d0ede5..daf22f5 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ This repository contains examples that use [Hono](https://hono.dev).
 - [env-vars](./env-vars/) - example using environment variables with Hono in Typescript: `Bindings` & `Variables`
 - [jsx-ssr](./jsx-ssr/) - JSX Server Side Rendering with `JSX` Middleware
 - [hono-vite-jsx](./hono-vite-jsx/) - Example of using `hono/jsx/dom` with `vite`
-- [serve-static](./serve-static/) - example of `Serve Static` Middleware
+- [serve-static](./serve-static/) - example of serving static files using Cloudflare Workers
 - [deno](./deno/) - Deno example
 - [bun](./bun/) - Bun example
 - [pages-stack](./pages-stack/) - Zod + Zod Validator + `hc` + React on Cloudflare Pages
diff --git a/serve-static/README.md b/serve-static/README.md
new file mode 100644
index 0000000..121372c
--- /dev/null
+++ b/serve-static/README.md
@@ -0,0 +1,13 @@
+# Hono static file example for Cloudflare Workers
+
+This example demonstrates how to serve static files using Cloudflare Workers. Please learn more in the [Hono documentation](https://hono.dev/docs/getting-started/cloudflare-workers#serve-static-files) and [Cloudflare Workers documentation](https://developers.cloudflare.com/workers/static-assets/binding/#directory).
+
+Before you can start publishing your service to cloudflare worker, you must sign up for a Cloudflare Workers account first, you can check out this [document](https://developers.cloudflare.com/workers/get-started/guide)
+
+You can update the information (`name`, `zone_id`, etc) in wrangler file, then you can test and deploy your service by simply doing,
+
+```txt
+npm install
+npm run dev # Start a local server for developing your worker
+npm run deploy # Publish your worker to the orange cloud
+```
diff --git a/serve-static/assets/folder/nested-file.txt b/serve-static/assets/folder/nested-file.txt
new file mode 100644
index 0000000..79f9c70
--- /dev/null
+++ b/serve-static/assets/folder/nested-file.txt
@@ -0,0 +1 @@
+This is a nested sample file
\ No newline at end of file
diff --git a/serve-static/assets/my-file.txt b/serve-static/assets/my-file.txt
new file mode 100644
index 0000000..b4f8b36
--- /dev/null
+++ b/serve-static/assets/my-file.txt
@@ -0,0 +1 @@
+This is a sample file
\ No newline at end of file
diff --git a/serve-static/package.json b/serve-static/package.json
new file mode 100644
index 0000000..9849b5c
--- /dev/null
+++ b/serve-static/package.json
@@ -0,0 +1,19 @@
+{
+  "name": "serve-static",
+  "version": "0.0.1",
+  "private": true,
+  "type": "module",
+  "scripts": {
+    "dev": "wrangler dev src/index.ts",
+    "deploy": "wrangler deploy src/index.ts"
+  },
+  "license": "MIT",
+  "dependencies": {
+    "hono": "^4.2.4"
+  },
+  "devDependencies": {
+    "@cloudflare/workers-types": "^4.20240405.0",
+    "vitest": "^1.5.0",
+    "wrangler": "^3.53.0"
+  }
+}
diff --git a/serve-static/src/index.ts b/serve-static/src/index.ts
new file mode 100644
index 0000000..f38c771
--- /dev/null
+++ b/serve-static/src/index.ts
@@ -0,0 +1,29 @@
+import { Hono } from "hono";
+import { poweredBy } from "hono/powered-by";
+
+const app = new Hono();
+
+// Mount Builtin Middleware
+app.use("*", poweredBy());
+
+// Routing
+app.get("/", (c) =>
+  c.html(
+    `<html lang="en">
+      <head>
+      <title>Hono</title>
+    </head>
+    <body>
+      <h1>Welcome to Hono</h1>
+      <p>
+        Try visiting: <a href="/my-file.txt">/my-file.txt</a> and <a href="/folder/nested-file.txt">/folder/nested-file.txt</a>
+      </p>
+      <p>
+        Learn more about serving static files in Hono <a target="_blank" href="https://hono.dev/docs/getting-started/cloudflare-workers#serve-static-files">here</a>
+      </p>
+    </body>
+  </html>`
+  )
+);
+
+export default app;
diff --git a/serve-static/tsconfig.json b/serve-static/tsconfig.json
new file mode 100644
index 0000000..2fba1f8
--- /dev/null
+++ b/serve-static/tsconfig.json
@@ -0,0 +1,18 @@
+{
+  "compilerOptions": {
+    "target": "ESNext",
+    "module": "ESNext",
+    "moduleResolution": "Bundler",
+    "esModuleInterop": true,
+    "strict": true,
+    "lib": [
+      "ESNext"
+    ],
+    "types": [
+      "vitest/globals",
+      "@cloudflare/workers-types"
+    ],
+    "jsx": "react-jsx",
+    "jsxImportSource": "hono/jsx"
+  },
+}
\ No newline at end of file
diff --git a/serve-static/wrangler.toml b/serve-static/wrangler.toml
new file mode 100644
index 0000000..4ee3116
--- /dev/null
+++ b/serve-static/wrangler.toml
@@ -0,0 +1,4 @@
+name = "hono-example-basic"
+compatibility_date = "2024-09-19"
+
+assets = { directory = "./assets/" }
\ No newline at end of file


Reviews:
user: login: yusukebe
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T05:44:45Z
user: login: erik-beus
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T14:19:07Z
user: login: yusukebe
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T22:30:20Z
user: login: yusukebe
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T22:30:32Z
user: login: erik-beus
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-04T07:28:25Z
user: login: erik-beus
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-04T07:28:37Z
user: login: yusukebe
body: LGTM!
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-04T07:36:36Z

Review comments:
path: serve-static/src/index.test.ts
user: login: yusukebe
body: Is this test file necessary?
created_at: 2025-03-03T05:44:23Z
author_association: MEMBER
path: serve-static/src/index.test.ts
user: login: erik-beus
body: No, it doesn't add value. If we wanted a test, we would need the test to run the application using `wrangler` I suppose.
I've removed the file :)
created_at: 2025-03-03T14:19:06Z
author_association: CONTRIBUTOR
path: serve-static/vitest.config.ts
user: login: yusukebe
body: Can you also remove this file? If this project does not have a test code, you can remove this!
created_at: 2025-03-03T22:30:08Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,20 @@
+{
+  "name": "serve-static",
+  "version": "0.0.1",
+  "private": true,
+  "type": "module",
+  "scripts": {
+    "dev": "wrangler dev src/index.ts",
+    "deploy": "wrangler deploy src/index.ts",
+    "test": "vitest --run"
path: serve-static/package.json
user: login: yusukebe
body: Please remove this line.
created_at: 2025-03-03T22:30:17Z
author_association: MEMBER
path: serve-static/src/index.test.ts
user: login: yusukebe
body: Thanks!
created_at: 2025-03-03T22:30:32Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,20 @@
+{
+  "name": "serve-static",
+  "version": "0.0.1",
+  "private": true,
+  "type": "module",
+  "scripts": {
+    "dev": "wrangler dev src/index.ts",
+    "deploy": "wrangler deploy src/index.ts",
+    "test": "vitest --run"
path: serve-static/package.json
user: login: erik-beus
body: Done ✅ 
created_at: 2025-03-04T07:28:25Z
author_association: CONTRIBUTOR
path: serve-static/vitest.config.ts
user: login: erik-beus
body: It's now removed ✅ 
created_at: 2025-03-04T07:28:37Z
author_association: CONTRIBUTOR

PR comments:
user: login: yusukebe
created_at: 2025-03-03T05:45:29Z
body: @erik-beus 

I'm sorry for being super late. I've added the comment. Please check it!
author_association: MEMBER
user: login: yusukebe
created_at: 2025-03-04T07:37:13Z
body: @erik-beus 

Looks good! Merging. Thank you for your contribution!
author_association: MEMBER