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

Clicking anchor links to valid static files results in a 404 and $error component showing #1295

Closed
leereamsnyder opened this issue May 1, 2021 · 11 comments

Comments

@leereamsnyder
Copy link

Describe the bug
I noticed this when updating from @sveltejs/kit from next-84 to next-94. If you have an <a href="/some-static-file.png"> link to any static asset, when you click the link, the SPA renders the $error layout with a 404 Not Found.

Logs
There's nothing in the console, but the stack on the $error page has the following:

_get_navigation_result@http://localhost:3000/.svelte/dev/runtime/internal/start.js:625:11
update@http://localhost:3000/.svelte/dev/runtime/internal/start.js:508:38
_navigate@http://localhost:3000/.svelte/dev/runtime/internal/start.js:233:23
init/<@http://localhost:3000/.svelte/dev/runtime/internal/start.js:143:9
EventListener.handleEvent*init@http://localhost:3000/.svelte/dev/runtime/internal/start.js:100:19
start@http://localhost:3000/.svelte/dev/runtime/internal/start.js:1004:20
async*@http://localhost:3000/:222:9

To Reproduce

I have a quick public repo with a minimal change to the sample project here if you want to pull that down: https://github.com/leereamsnyder/sveltekit-static-file-link-busted/blob/768fe93c2974ece2538be30a3d75c2af6cccd29b/src/routes/index.svelte#L29-L32

  1. Follow the Getting Started guide to create a sample project. I accepted all defaults.
  2. Start up with npm run dev
  3. In a route component, add an anchor link to an existing static file. In the starter project index page, for example, I added <a href="svelte-welcome.png">link to an image</a>
  4. Click the resulting link in the browser. You'll see an error page. If you reload at that point, you'll get the actual file, so the static server appears to be working generally.

Screen Shot 2021-05-01 at 1 52 37 PM

Expected behavior

The browser should render the static file instead of the SPA rendering an $error page.

Stacktraces
If you have a stack trace to include, we recommend putting inside a <details> block for the sake of the thread's readability:

Stack trace from the $error component
_get_navigation_result@http://localhost:3000/.svelte/dev/runtime/internal/start.js:625:11
update@http://localhost:3000/.svelte/dev/runtime/internal/start.js:508:38
_navigate@http://localhost:3000/.svelte/dev/runtime/internal/start.js:233:23
init/<@http://localhost:3000/.svelte/dev/runtime/internal/start.js:143:9
EventListener.handleEvent*init@http://localhost:3000/.svelte/dev/runtime/internal/start.js:100:19
start@http://localhost:3000/.svelte/dev/runtime/internal/start.js:1004:20
async*@http://localhost:3000/:222:9

Information about your SvelteKit Installation:

Diagnostics
  • The output of npx envinfo --system --npmPackages svelte,@sveltejs/kit,vite --binaries --browsers:
  System:
    OS: macOS 11.2.3
    CPU: (8) x64 Intel(R) Core(TM) i5-1030NG7 CPU @ 1.10GHz
    Memory: 120.70 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 15.11.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 7.7.5 - /usr/local/bin/npm
  Browsers:
    Chrome: 90.0.4430.93
    Safari: 14.0.3
    Safari Technology Preview: 14.2
  npmPackages:
    @sveltejs/kit: next => 1.0.0-next.94 
    svelte: ^3.34.0 => 3.38.1 
    vite: ^2.1.0 => 2.2.3 
  • Your browser: Firefox 88.0 64 Bit

  • Your adapter (e.g. Node, static, Vercel, Begin, etc...): this happens in development and with adapter-static

Severity
This is blocking my upgrade to the latest SvelteKit, but I could roll back to next-84 and it was fine.

@benmccann
Copy link
Member

benmccann commented May 2, 2021

I suspect that adding rel=external to your link would make this work: https://kit.svelte.dev/docs#anchor-options-rel-external. You may also might be able to make it work by putting the full URL (i.e. starting with https://)

@leereamsnyder
Copy link
Author

Ah, yeah, rel="external" does result in normal browser navigation here.

I think I misunderstood the docs on this one. They say:

By default, the SvelteKit runtime intercepts clicks on <a> elements and bypasses the normal browser navigation for relative (same-origin) URLs that match one of your page routes.

So I took it to mean you need rel=external on links that are a match to page routes where you want the browser, not SvelteKit, to handle the navigation for some reason. Like an escape hatch from the runtime, I suppose.

The behavior is more like "the SvelteKit runtime intercepts clicks on <a> elements and bypasses the normal browser navigation for relative (same-origin) URLs that match one of your page routes and displays an error 404 page if it doesn't match a route", which was the surprise to me.

Put another way, I expected it to be more like:

The SvelteKit runtime intercepts clicks on <a> elements and bypasses the normal browser navigation for relative (same-origin) URLs that match one of your page routes; for relative URLs that do not match a page route, expect normal browser navigation.

I've got a handful of documents in markdown that link to internal static files, so I'll have to update my MD->HTML conversion to add rel=external to anchors or update them to use HTML for the links or have the runtime add the rel=external, so that's a little inconvenient, but not too rough.

Happy to submit a little PR to the docs around this if you think it'd be helpful

@benmccann benmccann added this to the 1.0 milestone May 2, 2021
@benmccann
Copy link
Member

I think it's weird that you have to put rel=external on a link that's not actually external to your site. At the very least, we should introduce a sveltekit:external. We might also consider providing a user-configurable option that takes the path to return whether to attempt to route it so that the user can say that anything under static or anything ending in .png, .gif, etc. is not handled by the router

@lovasoa
Copy link
Contributor

lovasoa commented May 20, 2021

Couldn't this be done automatically, with neither sveltekit:external nor a custom user-provided function ? SvelteKit does already know which assets it has at build time.

@benmccann
Copy link
Member

But then we'd have to send a list of all assets to the client which would increase transfer latency

@lovasoa
Copy link
Contributor

lovasoa commented May 20, 2021

Why would it have to be sent to the client ? It is known at compile time, so the <a> tags that point to static files could just be compiled differently.

@benmccann
Copy link
Member

I suppose you could write a preprocessor that would automatically add sveltekit: external for you. Though that would add to compilation time so I'm not sure it'd be worth it

@lovasoa
Copy link
Contributor

lovasoa commented May 20, 2021

So there is no way to efficiently solve this bug ?

Maybe sveltekit navigation could just attempt a normal browser navigation whenever a route is not found ?

@madeleineostoja
Copy link

What about links that you don't know the exact href of ahead of time? For example those set in a CMS, where it might link to a valid route or a file, both 'internal' assuming assets are downloaded SSG style at build time.

@jasonbuckboyer
Copy link

jasonbuckboyer commented May 30, 2021

I think using sveltekit:external would be misleading as it's easily confused with rel="external" which has the semantic meaning of leaving your current site.

sveltekit needs an attribute to handle the cases of dynamic links and/or content pulled from a CMS, but it should be named something like sveltekit:static-link or similar.

That said, it would be nice in the long-term for sveltekit to automatically handle this for the cases it can.

@benmccann benmccann removed this from the 1.0 milestone Aug 3, 2021
flicksolutions pushed a commit to critique-digitale/critique-digitale.ch that referenced this issue Feb 17, 2022
because svelteKit intercepts normal anchor behaviour it tries to route to a page with the assets path. It does not exist, so it generates an error. See sveltejs/kit#1295
@mrkishi
Copy link
Member

mrkishi commented Mar 1, 2022

This isn't the case anymore since next.285 (which included #4070).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants