1

I'm building a portfolio project using SvelteKit and hosting it on Vercel using serverless funcitons. I'm using SvelteKit for everything, from routing to serverless function implementation. The problem that I'm having is that everything works 100% when I test locally using npm run dev and even when I build the app locally using npm run build and test using npm run preview, but after it gets pushed to Vercel if you go to /dashboard and refresh it sends the file as a octet-stream file instead of an HTML file, causing the browser to download it.

If you register with the site and then get redirected to /dashboard everything works fine, but once you're there if you refresh the browser it will download a file. I've noticed that inside of the .vercel_build_output folder there is an index.html file and a dashboard file with no file extension.

What I've tried so far:

  • Updated all NPM packages
  • Hosted on Netlify with adapter-netlify to see if it was a Vercel specific problem, it does the same thing but instead of an octet-stream file it just sends a txt file
  • Disabled prerendering for all pages. There is no plaintext dashboard file in the .vercel_build_output folder anymore but on refresh it shows a page that says [Object object] instead of sending a HTML/octet-stream file
  • Removed load function inside dashboard __layout.svelte since it's the only page with a load function. It breaks the page since it can't fetch user data but it still sends a file on refresh
  • Changed filesystem structure inside of the project to try to get it to build correctly

Links:

SvelteKit is a pretty young tool so this whole issue could be a bug but I don't know enough to be able to tell if I'm being a goofball or if it's a bug! I've been getting beat up by this problem for a few days so any help is VERY appreciated!

2 Answers 2

2

Your hooks.js handle() method checks if the path starts with "dashboard" and tries to return a 303 redirect response. However, the Response object is missing the 'Redirect' body. If the body is added it no longer results in [Object object].

This is definitely what is happening during prerendering, but I'm not sure why this would happen after registering. authToken would presumably be defined. Perhaps there is another bug in the auth/cookie code. (Ah, maybe the prerendered dashboard text file was being loaded from the static folder.)

Sign up to request clarification or add additional context in comments.

Comments

2

My issue ended up having two causes:

  1. My AuthToken cookie was not getting sent to the server side because of the SameSite attribute on refresh for some reason, I'm assuming this may have something to do with the serverless environment I'm working off of.

  2. Leftium was right, the issue had something to do with my hooks.js file and it was something to do with the redirects even though the user shouldn't be hitting them if they are authorized. If I commented out the code in my handle function and only had the following code it would redirect normally:

export async function handle({ event, resolve }) {
  const response = await resolve(event);
  return response;
}

The solution: I set SameSite to none on my authToken cookie and instead of using a hooks.js file to protect my endpoints that start with /dashboard I just protect each of them individually. I will do some more testing with the hooks.js file to see if I can find out the real cause.

Update: Leftium was 100% right, I just didn't include a body inside of a Response object in my handle function if the authToken was undefined but I did include one if there was an error parsing the JWT which is what I checked and did not verify that the previous Response object had a body as well. Furthermore, just as Leftium thought, there IS a bug inside of my code in the handle function that is causing the authToken to be undefined and cause the faulty Response object to be sent when deployed but not locally.

Update: There was not a bug in my handle function causing the authToken cookie to not be parsed. I looked into the build log and SvelteKit was prerendering the /dashboard api redirect to / so that /dashboard would always redirect to / without running the handle function. This only happened if my hooks.js file had the conditional redirect inside of the handle function. Even if I set prerendering to false in the /src/routes/dashboard/index.svelte to false npm run build would always prerender the redirect from the handle function. The "solution" was to disable prerendering for the whole app in svelte.config.js. Here is the relevant section of the build log:

  Prerendering
  303 /dashboard -> /
  200 /

Final Update: SvelteKit crawls through your code to determine what routes to prerender. SvelteKit was prerendering my redirect because when it crawled my code it would be redirected since it did not have an authToken cookie. I added this code to the top of my handle function inside of hooks.js and everything is working as expected in dev and prod!

import { prerendering } from '$app/env';

// prevents SvelteKit from prerendering the following redirect during build
if (prerendering) return await resolve(event);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.