Repository: honojs/hono
File: src/context.ts (TypeScript)

Code before:
  }

  /**
   * `.json()` can render JSON as `Content-Type:application/json`.
   *
   * @see {@link https://hono.dev/docs/api/context#json}
   *
   * @example
   * ```ts
   * app.get('/api', (c) => {
   *   return c.json({ message: 'Hello!' })
   * })
   * ```
   */
  json: JSONRespond = <
    T extends JSONValue | {} | InvalidJSONValue,
    U extends ContentfulStatusCode = ContentfulStatusCode,
  >(
    object: T,
    arg?: U | ResponseOrInit<U>,
    headers?: HeaderRecord
  ): JSONRespondReturn<T, U> => {
    const jsonString = JSON.stringify(object)
    return (
      !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized
        ? new Response(jsonString, {
            headers: { 'Content-Type': 'application/json' },
          })
        : this.#newResponse(jsonString, arg, setDefaultContentType('application/json', headers))
    ) /* eslint-disable @typescript-eslint/no-explicit-any */ as any
  }

  html: HTMLRespond = (
    html: string | Promise<string>,
    arg?: ContentfulStatusCode | ResponseOrInit<ContentfulStatusCode>,
    headers?: HeaderRecord
  ): Response | Promise<Response> => {
    const res = (html: string) =>
      this.#newResponse(html, arg, setDefaultContentType('text/html; charset=UTF-8', headers))
    return typeof html === 'object'
      ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res)
      : res(html)
  }

  /**
   * `.redirect()` can Redirect, default status code is 302.
   *
   * @see {@link https://hono.dev/docs/api/context#redirect}
   *
   * @example
   * ```ts

Review comment (suggestion):
I am wondering whether we should merge this PR, but regarding this, I think using `Response.json()` is better. It's simpler and faster: https://x.com/jarredsumner/status/2023328556210921948?s=20

```diff
diff --git a/src/context.ts b/src/context.ts
index 6b7949b9..f2a0edad 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -703,13 +703,14 @@ export class Context<
     arg?: U | ResponseOrInit<U>,
     headers?: HeaderRecord
   ): JSONRespondReturn<T, U> => {
-    const jsonString = JSON.stringify(object)
     return (
       !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized
-        ? new Response(jsonString, {
-            headers: { 'Content-Type': 'application/json' },
-          })
-        : this.#newResponse(jsonString, arg, setDefaultContentType('application/json', headers))
+        ? Response.json(object)
+        : this.#newResponse(
+            JSON.stringify(object),
+            arg,
+            setDefaultContentType('application/json', headers)
+          )
     ) /* eslint-disable @typescript-eslint/no-explicit-any */ as any
   }
```

Code after:
          text,
          arg,
          setDefaultContentType(TEXT_PLAIN, headers)
        ) as ReturnType<TextRespond>)
  }

  /**
   * `.json()` can render JSON as `Content-Type:application/json`.
   *
   * @see {@link https://hono.dev/docs/api/context#json}
   *
   * @example
   * ```ts
   * app.get('/api', (c) => {
   *   return c.json({ message: 'Hello!' })
   * })
   * ```
   */
  json: JSONRespond = <
    T extends JSONValue | {} | InvalidJSONValue,
    U extends ContentfulStatusCode = ContentfulStatusCode,
  >(
    object: T,
    arg?: U | ResponseOrInit<U>,
    headers?: HeaderRecord
  ): JSONRespondReturn<T, U> => {
    return (
      this.#useFastPath() && !arg && !headers
        ? Response.json(object)
        : this.#newResponse(
            JSON.stringify(object),
            arg,
            setDefaultContentType('application/json', headers)
          )
    ) as JSONRespondReturn<T, U>
  }

  html: HTMLRespond = (
    html: string | Promise<string>,
    arg?: ContentfulStatusCode | ResponseOrInit<ContentfulStatusCode>,
    headers?: HeaderRecord
  ): Response | Promise<Response> => {
    const res = (html: string) =>
      this.#newResponse(html, arg, setDefaultContentType('text/html; charset=UTF-8', headers))
    return typeof html === 'object'
      ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res)
      : res(html)
  }

  /**
   * `.redirect()` can Redirect, default status code is 302.