Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SvelteKit loads favicon every page request and messes up the request #3748

Closed
kvetoslavnovak opened this issue Feb 6, 2022 · 22 comments · Fixed by #5583
Closed

SvelteKit loads favicon every page request and messes up the request #3748

kvetoslavnovak opened this issue Feb 6, 2022 · 22 comments · Fixed by #5583
Labels
bug Something isn't working p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc.
Milestone

Comments

@kvetoslavnovak
Copy link
Contributor

kvetoslavnovak commented Feb 6, 2022

Describe the bug

I think there are two problems here:

  1. favicon.png is request on each navigation (why?)
  2. favicon in dev mode SOMETIMES is not found (404)

I have an API in SvelteKit structured as this
Screenshot from 2022-02-06 16-55-57

For some very strange reason SvelteKit tries to load favicon with every request in a very weird way.
SK

Moreover when I check the params of the request with values lang: 'en' and searched: '32015L2366' I see that there were two requests:
The first request:

Request {
  size: 0,
  follow: 20,
  compress: true,
  counter: 0,
  agent: undefined,
  highWaterMark: 16384,
  insecureHTTPParser: false,
  [Symbol(Body internals)]: {
    body: null,
    stream: null,
    boundary: null,
    disturbed: false,
    error: null
  },
  [Symbol(Request internals)]: {
    method: 'GET',
    redirect: 'follow',
    headers: {
      accept: 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
      'accept-encoding': 'gzip, deflate, br',
      'accept-language': 'en-US,en;q=0.9,cs;q=0.8',
      connection: 'keep-alive',
      referer: 'http://localhost:3000/en/favicon.png',
      'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="98"',
      'sec-ch-ua-mobile': '?0',
      'sec-ch-ua-platform': '"Linux"',
      'sec-fetch-dest': 'image',
      'sec-fetch-mode': 'no-cors',
      'sec-fetch-site': 'same-origin',
      'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36'
    },
    parsedURL: URL {
      href: 'http://localhost:3000/api/en/favicon.png.json',
      origin: 'http://localhost:3000',
      protocol: 'http:',
      username: '',
      password: '',
      host: 'localhost:3000',
      hostname: 'localhost',
      port: '3000',
      pathname: '/api/en/favicon.png.json',
      search: '',
      searchParams: URLSearchParams {},
      hash: ''
    },
    signal: null,
    referrer: undefined,
    referrerPolicy: ''
  }
}

Console logged params are:

{ lang: 'en', searched: 'favicon.png' }

The second request {correct one) is:

Request {
  size: 0,
  follow: 20,
  compress: true,
  counter: 0,
  agent: undefined,
  highWaterMark: 16384,
  insecureHTTPParser: false,
  [Symbol(Body internals)]: {
    body: null,
    stream: null,
    boundary: null,
    disturbed: false,
    error: null
  },
  [Symbol(Request internals)]: {
    method: 'GET',
    redirect: 'follow',
    headers: {
      accept: '*/*',
      'accept-encoding': 'gzip, deflate, br',
      'accept-language': 'en-US,en;q=0.9,cs;q=0.8',
      connection: 'keep-alive',
      host: 'localhost:3000',
      'if-none-match': '"1dyn90w"',
      referer: 'http://localhost:3000/en/32015L2366',
      'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="98"',
      'sec-ch-ua-mobile': '?0',
      'sec-ch-ua-platform': '"Linux"',
      'sec-fetch-dest': 'empty',
      'sec-fetch-mode': 'cors',
      'sec-fetch-site': 'same-origin',
      'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36'
    },
    parsedURL: URL {
      href: 'http://localhost:3000/api/en/32015L2366.json',
      origin: 'http://localhost:3000',
      protocol: 'http:',
      username: '',
      password: '',
      host: 'localhost:3000',
      hostname: 'localhost',
      port: '3000',
      pathname: '/api/en/32015L2366.json',
      search: '',
      searchParams: URLSearchParams {},
      hash: ''
    },
    signal: null,
    referrer: undefined,
    referrerPolicy: ''
  }

Console logged params are:

{ lang: 'en', searched: '32015L2366' }

Looks like a ghost in the shell.

Reproduction

See the structure in the picture above.

Logs

No response

System Info

Pop!_OS 21.10 , Browser info can be seen hereabove.

Severity

serious, but I can work around it

Additional Information

No response

@rumack
Copy link

rumack commented Feb 6, 2022

Same issue doing my head in all day, more or less identical to yours. Can't always reproduce it though, seems to happen randomly when opening a certain kind of content. I've tried a few things, the latest being to remove %svelte.assets% from this line: <link rel="icon" href="%svelte.assets%/favicon.png" /> in app.html. Hasn't happened in a few hours since that change and the favicon is still picked up fine from static folder...

@kvetoslavnovak
Copy link
Contributor Author

kvetoslavnovak commented Feb 6, 2022

Exactly, I have noticed the bug is not happening all the time. Which makes it even more strange.
I have tried to overcome the bug by loading the favicon manually in a __layout.svelte but it did not solve the problem neither.

@kvetoslavnovak
Copy link
Contributor Author

kvetoslavnovak commented Feb 6, 2022

I can confirm that "silencing" the bug by removal of %svelte.assets% from this line: link rel="icon" href="%svelte.assets%/favicon.png" in app.html.proposed by rumack helped for the time being.

@rumack
Copy link

rumack commented Feb 7, 2022

For info, I stumbled on this (same/similar) closed issue where you'll maybe find a better explanation and solution: #3582 (comment). See this too: #3234 (comment)

@kvetoslavnovak
Copy link
Contributor Author

There is also same issue discussed on StackOverflow SvelteKit loads favicon every page request

@frederikhors
Copy link
Contributor

I think there are two problems here:

  1. favicon.png is request on each navigation (why?)
  2. favicon in dev mode SOMETIMES is not found (404)

@kvetoslavnovak can you please update the issue accordingly with this numbered list if you agree?

It should be noted that even with old versions of SvelteKit (of December or even earlier) the favicon was requested at each navigation.

@niklasgrewe

This comment was marked as duplicate.

@Rich-Harris
Copy link
Member

Does setting the trailingSlash option to always (on platforms that need it) solve the issue, per #3582 (comment)? If not, can someone provide a minimal repro?

@frederikhors
Copy link
Contributor

Does setting the trailingSlash option to always (on platforms that need it) solve the issue, per #3582 (comment)?

Nope. I cannot create a repro now (due to lack of time).

@rumack
Copy link

rumack commented Mar 11, 2022

Sorry, just seeing these last exchanges now. I went back into the three Sveltekit apps where I was getting this error and reinserted %svelte.assets%/favicon.png, after adding trailingSlash: 'always' to svelte.config.js. Error seems to be gone. Using the node adapter.
Cheers!

@frederikhors
Copy link
Contributor

frederikhors commented Mar 11, 2022

I'm on SvelteKit v1.0.0-next.295 with adapter-static@1.0.0-next.29 and with or without trailingSlash: 'always' the favicon problem is still there.

I can fix it using a static <link rel="icon" href="/favicon.png" />.

Using %svelte.assets%/favicon.png instead doesn't work because in the inner pages it adds routes prefix to path, ex: /players/favicon.png instead of /favicon.png.

@rumack
Copy link

rumack commented Mar 11, 2022

Sorry, just seeing these last exchanges now. I went back into the three Sveltekit apps where I was getting this error and reinserted %svelte.assets%/favicon.png, after adding trailingSlash: 'always' to svelte.config.js. Error seems to be gone. Using the node adapter. Cheers!

Sorry, I spoke too soon. Error not fixed. I've had to remove the %svelte.assets% from app.html again. Otherwise I get 404 errors as it looks for routes that don't exist - somehow /favicon is appended onto normal routes which then can't be found...

@mattpilott
Copy link

Run into this issue today on vercel with latest auto adapter (35) and kit (317)
Screenshot 2022-04-21 at 10 37 30 am

@Rich-Harris
Copy link
Member

Again, we need a minimal repro if we're to investigate this. "See the structure in the picture above" does not count — see https://github.com/sveltejs/kit/blob/master/.github/ISSUE_TEMPLATE/bug_report.yml

@Vehmloewff
Copy link

Vehmloewff commented May 4, 2022

@Rich-Harris Thank you for all the work you've put into the svelte ecosystem. I'm sure I can speak for many of us in the community when I say that we are very grateful for the toolkit you've been building.

This issue has been plaguing me 😂! I've created a minimal reproduction here:

https://github.com/Vehmloewff/sveltekit-favicon-request

My Workaround
The main problem with this bug is that routes receive extra requests with route param values that are incorrectly "favicon.png". These requests can be ignored by simply placing these lines at the top of the handle function in hooks.ts

for (const param in event.params) {
    const value = event.params[param];
    if (value === 'favicon.png')
        return new Response('Ugg!  One of those extra requests again!', { status: 400 });
}

@Rich-Harris
Copy link
Member

Here's what I see when I run that reproduction locally — it works correctly, whether I'm doing a server-side or client-side navigation:

image

Aside: this isn't the point of this issue, but in the repro README you ask

And why is there an SSR request anyway? If we are going to ssr the page, should it not be done before the page is hydrated ;D?

The reason is that you're calling fetch when the component initialises. That fetch really belongs in the component's load function, but if you really must put it inside the component itself, it should be inside an onMount otherwise the fetch will happen during SSR but will have no effect (because by the time it resolves, the page has already rendered).

@Rich-Harris Rich-Harris added this to the 1.0 milestone May 11, 2022
@fehnomenal
Copy link
Contributor

I have a similar "problem" (quotes because it does not really break anything but my client wants to get rid of errors in the console).

I noticed that only Chrome/Chromium loads the favicon on each navigation, on Firefox it is fine.

The issue (console errors) happens when the url generated by %svelte.assets% (which is relative) is no longer valid when resolving to the url after navigating. This happens when navigating from / with href="./favicon.png" to /foo/bar. Then the href stays the same but Chromium tries to resolve the favicon from /foo/favicon.png which is obviously incorrect.

Again this does not break anything but is only annoying.

@dangelomedinag
Copy link

@Rich-Harris try to reproduce it in stackblitz with no fruits. locally it happens if this is your first time doing npm run dev.

  • clone repo
  • npm i
  • add .env ( OMDB_API_KEY=eedc324b ) // not real project
  • npm run dev
  • click to the movie "Captain Marvel" or any other.

the [id] parameter of the /api route displays the following on the console

=======[7:53:11]=======
[id] === tt3438640]
=======[7:53:11]=======
[id] === favicon.png]
res => error: Incorrect IMDb ID.
===============

considerations:
you don't always get the error. This is usually the first time you've run npm run dev so you might want to try it a couple of times. in my case it makes a fetch call that should not happen, since the parameter [id=favicon.png] results in an incorrect IMDb ID of https://omdbapi.com/

cdp-svletekit-bug-favicon

this seems like a good explanation @fehnomenal #3748 (comment)

I have a similar "problem" (quotes because it does not really break anything but my client wants to get rid of errors in the console).

I noticed that only Chrome/Chromium loads the favicon on each navigation, on Firefox it is fine.

The issue (console errors) happens when the url generated by %svelte.assets% (which is relative) is no longer valid when resolving to the url after navigating. This happens when navigating from / with href="./favicon.png" to /foo/bar. Then the href stays the same but Chromium tries to resolve the favicon from /foo/favicon.png which is obviously incorrect.

Again this does not break anything but is only annoying.

@kilicbaran
Copy link

Doesn't happen on Firefox.
Happens on Chrome when you go into a subroute (e.g. from /a to /a/b). I think the reason for this that the link somehow doesn't update and Chrome requests the favicon again. Initially, the link is ./favicon.png and resolves to /favicon.png. When you go to /a/b the link is still same (./favicon.png) and now resolves to /a/favicon.png which is the wrong path and Chrome requests it again. When I refresh the page while I am on /a/b, the link becomes the correct one ../favicon.png and resolves to the correct /favicon.png.

@GauBen
Copy link
Contributor

GauBen commented Jul 15, 2022

I'm currently working on a fix, but I need some clarification on why does sveltekit use relative urls for assets:

const segments = event.url.pathname.slice(options.paths.base.length).split('/').slice(2);
const assets =
options.paths.assets || (segments.length > 0 ? segments.map(() => '..').join('/') : '.');
const html = await resolve_opts.transformPage({
html: options.template({ head, body, assets, nonce: /** @type {string} */ (csp.nonce) })
});

Here is what I suggest instead:

const assets = options.paths.assets || options.paths.base;

const html = await resolve_opts.transformPage({
  html: options.template({ head, body, assets, nonce: /** @type {string} */ (csp.nonce) })
});

I you still have this issue, could you please try patching node_modules/@sveltejs/kit/assets/server/index.js:1579 with the lines above and tell me if the bug still happens?

Edit: it looks like options.paths.assets and options.paths.base are equal unless .assets is set, making the fix even simpler: const assets = options.paths.assets

@jhwz
Copy link

jhwz commented Jul 17, 2022

@GauBen I'm pretty sure it's a relative path to allow things like #595. If %sveltekit.assets% is an absolute path it would make #595 impossible (I think)

@benmccann benmccann added bug Something isn't working p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc. labels Jul 19, 2022
Rich-Harris added a commit that referenced this issue Jul 20, 2022
…gating (#5583)

* make link hrefs absolute - fixes #3748

* ugh stfu eslint you miserable funsucker

* update test

* Create stupid-dolls-fly.md

* Update packages/kit/src/runtime/client/client.js

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>

* Update packages/kit/test/apps/basics/test/test.js

Co-authored-by: Rich Harris <richard.a.harris@gmail.com>

* see if this makes different tests fail on safari

* Revert "see if this makes different tests fail on safari"

This reverts commit 91049b7.

* i hate safari with the fire of a thousand suns

* Update .changeset/stupid-dolls-fly.md

* Update packages/kit/src/runtime/client/client.js

* Update packages/kit/src/runtime/client/client.js

* ugh this is easier than fighting with typescript

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
@OffBy0x01
Copy link

Just to add - for anyone else using the bun runtime that is still seeing this issue; I tried many things to resolve this locally but ultimately had to switch back to node. As soon as I swapped bun run dev for npm run dev I could no longer reproduce.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc.
Projects
None yet