# Response.text() Returns Garbled Text

**URL:** <https://answers.netlify.com/t/response-text-returns-garbled-text/118446>\
**Category:** Support\
**Tags:** edge\_functions, deployment\
**Created:** [May 13, 2024, 10:10am UTC](https://answers.netlify.com/t/response-text-returns-garbled-text/118446 "2024-05-13T10:10:11Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![bytrangle](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/bytrangle/32/16593_2.png) [@bytrangle](https://answers.netlify.com/u/bytrangle)\
**Post date:** [May 13, 2024, 10:10am UTC](https://answers.netlify.com/t/response-text-returns-garbled-text/118446/1 "2024-05-13T10:10:11Z")

</div>

Hi. In an Edge function, when I run:

```auto
const response = await context.next()
const text = response.text()
console.log(text)

```

The result is garbled text.

 ![Screenshot from 2024-05-13 10-03-49](https://global.discourse-cdn.com/netlify/original/3X/d/9/d9f9d969c781e245fa99d3c81ef4738207c50654.png)

Through eliminations, I believe this result was due to having `<meta>` tags.

```auto
 <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

```

For whatever reason, the response received wasn’t properly encoded.

[The page in problem](https://debug-unreadable-body--static-to-dynamic.netlify.app/cache-keys)

Here is the [file](https://github.com/bytrangle/netlify-caching/blob/debug_unreadable-body/src/layouts/BaseLayout.astro) that generates HTML for that page above.

---

<div class="post-metadata">

**Author:** ![hrishikesh](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/hrishikesh/32/74607_2.png) [@hrishikesh](https://answers.netlify.com/u/hrishikesh)\
**Post date:** [May 13, 2024, 10:49am UTC](https://answers.netlify.com/t/response-text-returns-garbled-text/118446/2 "2024-05-13T10:49:58Z")

</div>

Adding a trailing slash: [debug-unreadable-body–static-to-dynamic.netlify.app/cache-keys/](https://debug-unreadable-body--static-to-dynamic.netlify.app/cache-keys/) seems to solve the problem. So it doesn’t appear to be related to the meta tags, but could be something going wrong internally. I’ll ask the devs to check.

---

<div class="post-metadata">

**Author:** ![skn0tt](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/skn0tt/32/33874_2.png) [@skn0tt](https://answers.netlify.com/u/skn0tt)\
**Post date:** [May 13, 2024, 12:29pm UTC](https://answers.netlify.com/t/response-text-returns-garbled-text/118446/4 "2024-05-13T12:29:58Z")

</div>

Hey there! Simon from the Edge Functions team here. Welcome back to the forums 🎉

I checked your code, and have a hypothesis of what’s happening:

By default, the Netlify CDN redirects requests from `/foo` to `/foo/` (see [docs](https://docs.netlify.com/routing/redirects/redirect-options/#trailing-slash)). That means that for requests to `/cache-keys`, `context.next()` will return a `Response` with an empty body and a 301 status. Your code doesn’t take that into account. It takes that empty body and uses it in the 200 response. I’d expect that to result in an empty body, but apparently it results in garbled text, for whatever reason. I’ll make a note internally to investigate that, but I think this unrelated to your issue.

To check this hypothesis, could you try changing your edge function so that it only modifies 200 requests? A little like this:

```diff
import type { Config, Context } from "@netlify/edge-functions"

export default async (request: Request, context: Context) => {
  const response = await context.next()
+ if (response.status !== 200) return response
  const text = await response.text()
  console.log(text)
  return new Response(text, {
    headers: {
      "content-type": "text/html;charset=utf-8",
      "Cache-Control": "public, max-age=0, must-revalidate", // Tell browsers to always revalidate
      "Netlify-CDN-Cache-Control": "public, max-age=31536000, must-revalidate",
    }
  })
}

export const config: Config = {
  path: "/cache-keys"
}

```

Also, bonus tip - always try to prevent calling `response.text` if you can. That will buffer the response in memory and decrease your time to first byte significantly. You’re probably already aware of this and just used it for debugging purposes - still wanted to point it out 😃

---

<div class="post-metadata">

**Author:** ![bytrangle](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/bytrangle/32/16593_2.png) [@bytrangle](https://answers.netlify.com/u/bytrangle)\
**Post date:** [May 14, 2024, 8:37am UTC](https://answers.netlify.com/t/response-text-returns-garbled-text/118446/5 "2024-05-14T08:37:51Z")

</div>

Thanks for getting back. Your suggestion works.  
Did you mean “prevent logging `response.text`”? Because I intend to modify the response, so there is no way getting around calling `await response.text()`?

---

<div class="post-metadata">

**Author:** ![skn0tt](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/skn0tt/32/33874_2.png) [@skn0tt](https://answers.netlify.com/u/skn0tt)\
**Post date:** [May 14, 2024, 9:09am UTC](https://answers.netlify.com/t/response-text-returns-garbled-text/118446/6 "2024-05-14T09:09:42Z")

</div>

If you only need to attach caching headers, then there’s no need to call `response.text`. Here’s an example:

```js
export default async (request, context) => {
   const response = await context.next()
   return new Response(response.body, {
      headers: {
           "foo": "bar",
           ...response.headers // this is important, so you don't swallow headers!
      }
   })
}

```

Or, even simpler:

```js
export default async (request, context) => {
   const response = await context.next()
   response.headers.set("foo", "bar")
   return response
}

```

If your usecase requires modifying the response body, then you can do that using a Streaming Transform:

```js
export default async (request, context) => {
   const response = await context.next()
   const transformer = new TransformStream({
      transform(chunk, controller) {
         controller.enqueue(doTransform(chunk))
      }
   })
   return new Response(response.body.pipeThrough(transformer), response)
}

```

Compared to `response.text()`, which buffers the full response body before you can process it, this TransformStream approach allows you to transform the body as it arrives.

This is not an optimisation you absolutely need, but if your site has performance constraints (think marketing pages or e-commerce) then you should always try to prevent buffering.

---

<div class="post-metadata">

**Author:** ![bytrangle](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/bytrangle/32/16593_2.png) [@bytrangle](https://answers.netlify.com/u/bytrangle)\
**Post date:** [May 16, 2024, 4:12pm UTC](https://answers.netlify.com/t/response-text-returns-garbled-text/118446/7 "2024-05-16T16:12:19Z")

</div>

Hi, just an update: Does the streaming transform work for you? I got an error “Readable stream is unlocked”. May be I don’t need to read stream, but I’d like to explore if it is possible.

---

<div class="post-metadata">

**Author:** ![skn0tt](https://sea1.discourse-cdn.com/netlify/user_avatar/answers.netlify.com/skn0tt/32/33874_2.png) [@skn0tt](https://answers.netlify.com/u/skn0tt)\
**Post date:** [May 16, 2024, 4:35pm UTC](https://answers.netlify.com/t/response-text-returns-garbled-text/118446/8 "2024-05-16T16:35:15Z")

</div>

That sounds like you’re trying to read the stream and then transform it. That won’t work, you can only have a single reader - take a look at [ReadableStream: tee() method - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/tee) if you absolutely need to read it twice.
