chore: Added formatting 92bab845
Steve · 2025-05-07 20:17 3 file(s) · +132 −108
docs/components/Landing.tsx +69 −45
1 -
import { useState } from 'react'
1 +
import { useState } from "react";
2 2
3 3
export function Landing() {
4 -
  const [copied, setCopied] = useState(false)
4 +
	const [copied, setCopied] = useState(false);
5 5
6 +
	const copyToClipboard = async () => {
7 +
		try {
8 +
			await navigator.clipboard.writeText("bun create bhvr@latest");
9 +
			setCopied(true);
10 +
			setTimeout(() => setCopied(false), 2000);
11 +
		} catch (err) {
12 +
			console.error("Failed to copy:", err);
13 +
		}
14 +
	};
6 15
7 -
  const copyToClipboard = async () => {
8 -
    try {
9 -
      await navigator.clipboard.writeText('bun create bhvr@latest')
10 -
      setCopied(true)
11 -
      setTimeout(() => setCopied(false), 2000)
12 -
    } catch (err) {
13 -
      console.error('Failed to copy:', err)
14 -
    }
15 -
  }
16 -
17 -
  return (
18 -
    <main className="flex max-w-lg sm:max-w-2xl mx-auto flex-col items-center justify-start p-4 ">
19 -
      <div className="w-full max-w-2xl flex flex-col items-center gap-8">
20 -
        <div className="flex flex-col items-center gap-3">
21 -
          <p className="text-xl text-muted-foreground">Bun + Hono + Vite + React</p>
22 -
          <p className="text-center max-w-md">Modern and lightweight stack for the open web</p>
23 -
        </div>
24 -
25 -
        <div className="w-full">
26 -
          <div className="relative w-full rounded-lg bg-zinc-800 p-4 overflow-hidden">
27 -
            <pre className="text-sm font-mono">
28 -
              <code>bun create bhvr@latest</code>
29 -
            </pre>
30 -
            <button
31 -
              className="absolute top-2 right-2 rounded-md p-2 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none"
32 -
              onClick={copyToClipboard}
33 -
            >
34 -
              {copied ? (
35 -
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="h-4 w-4">
36 -
                  <polyline points="20 6 9 17 4 12"></polyline>
37 -
                </svg>
38 -
              ) : (
39 -
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="h-4 w-4">
40 -
                  <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
41 -
                  <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
42 -
                </svg>
43 -
              )}
44 -
            </button>
45 -
          </div>
46 -
        </div>
47 -
      </div>
16 +
	return (
17 +
		<main className="flex max-w-lg sm:max-w-2xl mx-auto flex-col items-center justify-start p-4 ">
18 +
			<div className="w-full max-w-2xl flex flex-col items-center gap-8">
19 +
				<div className="flex flex-col items-center gap-3">
20 +
					<p className="text-xl text-muted-foreground">
21 +
						Bun + Hono + Vite + React
22 +
					</p>
23 +
					<p className="text-center max-w-md">
24 +
						Modern and lightweight stack for the open web
25 +
					</p>
26 +
				</div>
48 27
49 -
    </main>
50 -
  )
28 +
				<div className="w-full">
29 +
					<div className="relative w-full rounded-lg bg-zinc-800 p-4 overflow-hidden">
30 +
						<pre className="text-sm font-mono">
31 +
							<code>bun create bhvr@latest</code>
32 +
						</pre>
33 +
						<button
34 +
							className="absolute top-2 right-2 rounded-md p-2 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none"
35 +
							onClick={copyToClipboard}
36 +
						>
37 +
							{copied ? (
38 +
								<svg
39 +
									xmlns="http://www.w3.org/2000/svg"
40 +
									width="16"
41 +
									height="16"
42 +
									viewBox="0 0 24 24"
43 +
									fill="none"
44 +
									stroke="currentColor"
45 +
									strokeWidth="2"
46 +
									strokeLinecap="round"
47 +
									strokeLinejoin="round"
48 +
									className="h-4 w-4"
49 +
								>
50 +
									<polyline points="20 6 9 17 4 12"></polyline>
51 +
								</svg>
52 +
							) : (
53 +
								<svg
54 +
									xmlns="http://www.w3.org/2000/svg"
55 +
									width="16"
56 +
									height="16"
57 +
									viewBox="0 0 24 24"
58 +
									fill="none"
59 +
									stroke="currentColor"
60 +
									strokeWidth="2"
61 +
									strokeLinecap="round"
62 +
									strokeLinejoin="round"
63 +
									className="h-4 w-4"
64 +
								>
65 +
									<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
66 +
									<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
67 +
								</svg>
68 +
							)}
69 +
						</button>
70 +
					</div>
71 +
				</div>
72 +
			</div>
73 +
		</main>
74 +
	);
51 75
}
docs/pages/packages/server.mdx +61 −62
1 -
import { Button } from 'vocs/components'
1 +
import { Button } from "vocs/components";
2 2
3 3
# `server`
4 4
13 13
You can declare routes in your API like so
14 14
15 15
```typescript
16 -
import { Hono } from 'hono'
16 +
import { Hono } from "hono";
17 17
18 -
const app = new Hono()
18 +
const app = new Hono();
19 19
20 -
app.get('/', (c) => {
21 -
  return c.text('Hello Hono!')
22 -
})
20 +
app.get("/", (c) => {
21 +
  return c.text("Hello Hono!");
22 +
});
23 23
24 -
export default app
24 +
export default app;
25 25
```
26 26
27 27
Hono also makes it easy to add in path parameters
28 28
29 29
```typescript
30 -
app.get('/user/:name', async (c) => {
31 -
  const name = c.req.param('name')
30 +
app.get("/user/:name", async (c) => {
31 +
  const name = c.req.param("name");
32 32
  // ...
33 -
})
33 +
});
34 34
```
35 35
36 36
or multiple parameters
37 37
38 38
```typescript
39 -
app.get('/posts/:id/comment/:comment_id', async (c) => {
40 -
  const { id, comment_id } = c.req.param()
39 +
app.get("/posts/:id/comment/:comment_id", async (c) => {
40 +
  const { id, comment_id } = c.req.param();
41 41
  // ...
42 -
})
42 +
});
43 43
```
44 44
45 45
The `(c)` in Hono is the `Context` which has loads of primary features of your API.
47 47
**Access a Request**
48 48
49 49
```typescript
50 -
app.get('/hello', (c) => {
51 -
  const userAgent = c.req.header('User-Agent')
50 +
app.get("/hello", (c) => {
51 +
  const userAgent = c.req.header("User-Agent");
52 52
  // ...
53 -
})
53 +
});
54 54
```
55 55
56 56
**Return JSON or HTML**
57 57
58 58
```typescript
59 -
app.get('/api', (c) => {
60 -
  return c.json({ message: 'Hello!' })
61 -
})
59 +
app.get("/api", (c) => {
60 +
  return c.json({ message: "Hello!" });
61 +
});
62 62
```
63 63
64 64
```typescript
65 -
app.get('/', (c) => {
66 -
  return c.html('<h1>Hello! Hono!</h1>')
67 -
})
65 +
app.get("/", (c) => {
66 +
  return c.html("<h1>Hello! Hono!</h1>");
67 +
});
68 68
```
69 69
70 70
**Access an ENV**
72 72
```typescript
73 73
// Type definition to make type inference
74 74
type Bindings = {
75 -
  MY_KV: KVNamespace
76 -
}
75 +
  MY_KV: KVNamespace;
76 +
};
77 77
78 -
const app = new Hono<{ Bindings: Bindings }>()
78 +
const app = new Hono<{ Bindings: Bindings }>();
79 79
80 80
// Environment object for Cloudflare Workers
81 -
app.get('/', async (c) => {
82 -
  c.env.MY_KV.get('my-key')
81 +
app.get("/", async (c) => {
82 +
  c.env.MY_KV.get("my-key");
83 83
  // ...
84 -
})
84 +
});
85 85
```
86 86
87 87
## RPC
95 95
This will setup your API with the following code, and the key being the use of `const routes` and exporting the `AppType`
96 96
97 97
```typescript src/index.ts
98 -
import { Hono } from 'hono'
99 -
import { cors } from 'hono/cors'
100 -
import type { ApiResponse } from 'shared/dist'
98 +
import { Hono } from "hono";
99 +
import { cors } from "hono/cors";
100 +
import type { ApiResponse } from "shared/dist";
101 101
102 -
const app = new Hono()
102 +
const app = new Hono();
103 103
104 -
app.use(cors())
104 +
app.use(cors());
105 105
106 -
const routes = app.get('/', (c) => { //[!code focus]
107 -
  return c.text('Hello Hono!')
108 -
})
106 +
const routes = app
107 +
  .get("/", (c) => {
108 +
    //[!code focus]
109 +
    return c.text("Hello Hono!");
110 +
  })
109 111
110 -
.get('/hello', async (c) => {
112 +
  .get("/hello", async (c) => {
113 +
    const data: ApiResponse = {
114 +
      message: "Hello BHVR!",
115 +
      success: true,
116 +
    };
111 117
112 -
  const data: ApiResponse = {
113 -
    message: "Hello BHVR!",
114 -
    success: true
115 -
  }
118 +
    return c.json(data, { status: 200 });
119 +
  });
116 120
117 -
  return c.json(data, { status: 200 })
118 -
})
119 -
120 -
export type AppType = typeof routes // [!code focus]
121 -
export default app
121 +
export type AppType = typeof routes; // [!code focus]
122 +
export default app;
122 123
```
123 124
124 125
In your `client` code Hono is installed as a dependency, and the `hc` client is imported and initialized. The `AppType` is also used so we can build types with it.
181 182
app.get("/query/users/:id", async (c) => {
182 183
  const userId = c.req.param("id");
183 184
  try {
184 -
    let { results } = await c.env.DB.prepare(
185 -
      "SELECT * FROM users WHERE user_id = ?",
186 -
    )
185 +
    let { results } = await c.env.DB.prepare("SELECT * FROM users WHERE user_id = ?")
187 186
      .bind(userId)
188 187
      .all();
189 188
    return c.json(results);
207 206
208 207
```typescript
209 208
type Bindings = {
210 -
  MY_BUCKET: R2Bucket
211 -
  USERNAME: string
212 -
  PASSWORD: string
213 -
}
209 +
  MY_BUCKET: R2Bucket;
210 +
  USERNAME: string;
211 +
  PASSWORD: string;
212 +
};
214 213
215 -
const app = new Hono<{ Bindings: Bindings }>()
214 +
const app = new Hono<{ Bindings: Bindings }>();
216 215
217 216
// Access to environment values
218 -
app.put('/upload/:key', async (c, next) => {
219 -
  const key = c.req.param('key')
220 -
  await c.env.MY_BUCKET.put(key, c.req.body)
221 -
  return c.text(`Put ${key} successfully!`)
222 -
})
217 +
app.put("/upload/:key", async (c, next) => {
218 +
  const key = c.req.param("key");
219 +
  await c.env.MY_BUCKET.put(key, c.req.body);
220 +
  return c.text(`Put ${key} successfully!`);
221 +
});
223 222
```
224 223
225 224
To set these variables, public ones can be put inside the `wrangler.jsonc` or `wrangler.toml` file.
234 233
  //   "nodejs_compat"
235 234
  // ],
236 235
  "vars": {
237 -
    "MY_VAR": "my-variable"
236 +
    "MY_VAR": "my-variable",
238 237
  },
239 238
  "kv_namespaces": [
240 239
    {
241 240
      "binding": "MY_KV_NAMESPACE",
242 -
      "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
243 -
    }
241 +
      "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
242 +
    },
244 243
  ],
245 244
  // "r2_buckets": [
246 245
  //   {
package.json +2 −1
6 6
  "scripts": {
7 7
    "dev": "vocs dev",
8 8
    "build": "vocs build -o ../dist",
9 -
    "preview": "vocs preview"
9 +
    "preview": "vocs preview",
10 +
    "format": "bunx biome format --write ./docs"
10 11
  },
11 12
  "dependencies": {
12 13
    "react": "latest",