Request data
| API | Value |
|---|---|
| c.req | Native Request |
| c.params | Path parameters; strings unless schema coercion applies |
| c.query | Query values; repeated keys become arrays |
| c.headers | Native Headers; read with get(name) |
| c.body | Parsed POST/PUT/PATCH body |
| c.store | Application decoration store; shared across requests |
| c.url, c.path, c.method | Parsed URL, pathname, and HTTP method |
Complete example
index.ts
import { Volt } from 'voltts';
const app = new Volt();
app.get('/users/:id', (c) => {
c.setHeader('X-Example', 'volt');
return c.json({
id: c.params.id,
profile: c.query.profile === 'true',
accept: c.headers.get('accept'),
});
});
app.get('/text', (c) => c.text('Hello Volt'));
app.get('/html', (c) => c.html('<h1>Hello Volt</h1>'));
app.get('/redirect', (c) => c.redirect('/text'));
app.post('/echo', (c) => c.json({ body: c.body }, 201));
if (globalThis._importMeta_.main) app.listen(3000);
export default app;Try request and response helpers
bash
bun run index.ts
curl -i 'http://localhost:3000/users/42?profile=true'
curl -i -X POST http://localhost:3000/echo -H 'Content-Type: application/json' -d '{"title":"Coffee"}'Use c.json(data, status), c.text(text, status), c.html(html, status), c.redirect(url, status), and c.setHeader(name, value). Prefer explicit status arguments such as c.json(data, 201). A returned object becomes JSON; null or undefined becomes an empty 204 response.
Body and state rules
POST, PUT, and PATCH bodies are parsed before the handler. Use await c.parseBody() explicitly for methods outside that set when needed. Read multipart data with c.file(), c.files(), or c.formData(). Do not consume c.req.json() after automatic parsing. c.store is shared application state: keep per-request identity and temporary values in local variables rather than adding them to this store.