Worker strange behavior blank page

I am trying to get a worker to work. What I am trying to do is first detect mobile devices and redirect any requests coming from a mobile device to another URL.
The second thing is injecting Google Tag Manager snippets into the site.

This works as expected:

addEventListener('fetch', event => {

 * Fetch and log a request
 * @param {Request} request
async function handleRequest(request) {
  let userAgent = request.headers.get('user-agent')

  if (userAgent.match(/(iphone)|(ipod)|(ipad)|(android)|(blackberry)|(windows phone)|(symbian)/i)) {
    console.log('mobile device detected: ' + userAgent)
    const requestURL = new URL('')
    return Response.redirect(requestURL, 302)

  const response = await fetch(request)
  let html = await response.text()

	const googleTagManagerHeader = "<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=''+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-WN2XN6C');</script></head>"
	html = html.replace( /<\/head>/ , googleTagManagerHeader)

	const googleTagManagerBody = '<body><noscript><iframe src="" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>'
	html = html.replace( /<body>/ , googleTagManagerBody)
	return new Response(html, {
		headers: response.headers

But there is one problem with it. When I access the page itself I just get a blank page with no response body returned at all. When I reload the site using CTRL+F5 (hard reload) the site loads perfectly fine while even redirecting mobile devices and injecting the Google Snippet.

I’m really out of ideas as to why this behaves like it does??


Is it possible to be related to Google Tag Manager?

No, it behaves like that even if I do nothing but return the original request in the handleRequest function.

Perhaps fetch() is returning a 304 response? I think your script would translate that into a blank 200 response, as currently written.

I just debugged and indeed it returns a 302. Now I am more confused as before

Ah, perhaps your origin is serving a 302 with no body? That would have the same effect. You could try having fetch() follow redirects with fetch(request, { redirect: "follow" }) and see if that changes things? I think you might still end up having to deal with 304 responses, though.

I feel like I am getting closer. I now tried to remove the headers: response.headers in my new Response. Now I can see the content, although it displays it in plain text. Is there a way to get the headers from the original request before the redirect.

I now just manually set the content-type headers and now its working. Thanks for the hint with follow redirects!