This chapter covers upgrades for two types of legacy custom Server APIs:
These two approaches are mutually exclusive in the legacy version. When migrating, please choose the corresponding path based on the capabilities actually used in the project.
server/index.ts → server/modern.server.tsunstableMiddleware array → defineServerConfigc.req/c.res)next(), new version must call it for subsequent chain executionc.response.raw() → c.text() / c.json()// Legacy - server/index.ts
export const unstableMiddleware: UnstableMiddleware[] = [middleware1, middleware2];
// New - server/modern.server.ts
import { defineServerConfig } from '@modern-js/server-runtime';
export default defineServerConfig({
middlewares: [
{ name: 'middleware1', handler: middleware1 },
{ name: 'middleware2', handler: middleware2 },
],
});// Legacy
import type { UnstableMiddleware, UnstableMiddlewareContext } from '@modern-js/server-runtime';
const middleware: UnstableMiddleware = async (c: UnstableMiddlewareContext, next) => {
return c.response.raw('response'); // Will continue rendering even without calling next
};
// New
import { defineServerConfig, type MiddlewareHandler } from '@modern-js/server-runtime';
const middleware: MiddlewareHandler = async (c, next) => {
await next(); // Must call
return c.text('response');
};| Legacy API | New API | Description |
|---|---|---|
c.request.cookie | getCookie(c, 'key') | Cookie reading |
c.req.cookie() | getCookie(c, 'key') | Hono v4 deprecated |
c.request.pathname | c.req.path | Request path |
c.request.host | c.req.header('Host') | Request host |
c.request.query | c.req.query() | Query parameters |
c.request.headers | c.req.header() | Request headers |
c.response.status | c.status() | Response status code |
c.response.set | c.res.headers.set | Set response headers |
c.response.raw | c.text / c.json | Response body |
afterRender is only used for HTML processing after page rendering is complete.
import { defineServerConfig, type MiddlewareHandler } from '@modern-js/server-runtime';
const renderMiddleware: MiddlewareHandler = async (c, next) => {
await next(); // Wait for page rendering first
const { res } = c;
const html = await res.text();
const modified = html
.replace('<head>', '<head><meta name="author" content="ByteDance">')
.replace('<body>', '<body><div id="loading">Loading...</div>')
.replace('</body>', '<script>console.log("Page loaded")</script></body>');
c.res = c.body(modified, { status: res.status, headers: res.headers });
};
export default defineServerConfig({
renderMiddlewares: [{ name: 'custom-content-injection', handler: renderMiddleware }],
});