kit icon indicating copy to clipboard operation
kit copied to clipboard

svelte-adapter-static: "404 Internal Error" with trailing index.html in URL

Open TomFevrier opened this issue 3 years ago • 5 comments

Describe the bug

My app is using svelte-adapter-static with the trailingSlash option set to 'always', so each route is a folder containing its own index.html. I use a static server so no SSR, but prerender is set to true in +layout.js.

It works fine when I navigate to /my-route or /my-route/, however when I explicitly navigate to /my-route/index.html, I get a 404 error (from the start-xxxxxxxx.js hydration script). Why is that? Because of the way my static server is configured, I usually need to explicitly set the URL with a trailing index.html, but it seems to break the hydration script.

Thank you very much!

Reproduction

https://stackblitz.com/edit/sveltekit-404-index-html?file=src/routes/my-route/+page.svelte

Logs

No response

System Info

System:
    OS: macOS 12.4
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 1.86 GB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.2.0 - ~/.nvm/versions/node/v18.2.0/bin/node
    npm: 8.9.0 - ~/.nvm/versions/node/v18.2.0/bin/npm
  Browsers:
    Chrome: 105.0.5195.125
    Firefox: 101.0.1
    Safari: 15.5
  npmPackages:
    @sveltejs/adapter-static: ^1.0.0-next.43 => 1.0.0-next.43 
    @sveltejs/kit: ^1.0.0-next.483 => 1.0.0-next.483 
    svelte: ^3.50.1 => 3.50.1 
    vite: ^3.1.1 => 3.1.1

Severity

blocking all usage of SvelteKit

Additional Information

No response

TomFevrier avatar Oct 31 '22 10:10 TomFevrier

Because of the way my static server is configured, I usually need to explicitly set the URL with a trailing index.html, but it seems to break the hydration script.

Can you share what static server you are using?

benmccann avatar Nov 09 '22 00:11 benmccann

Can you share what static server you are using?

I have no idea, it is beyond my control... All I know is that I need to explicitly add index.html to the URL in order for iframe integration to work.

But regardless of which static server I am using, suffixing the URL of a route with index.html should not break the page, should it? For example, using Surge:

  • https://lesechos-test-2.surge.sh/mix-electricite/ [WORKS]
  • https://lesechos-test-2.surge.sh/mix-electricite/index.html [BREAKS]

TomFevrier avatar Nov 12 '22 10:11 TomFevrier

This is working as designed — each page should have a single unambiguous URL, otherwise SEO suffers and things get weird with relative links. You can explicitly add the index.html to routes, like so...

-src/routes/my-route/+page.svelte
+src/routes/my-route/index.html/+page.svelte

...and /my-route/index.html will work (but /my-route won't). Does that solve your case?

Rich-Harris avatar Nov 17 '22 17:11 Rich-Harris

(though now that I think about it you might run into https://github.com/sveltejs/kit/issues/7244, if you have a +page.server.js alongside the +page.svelte, because SvelteKit will try and fail to write my-route/index.html and my-route/index.html/__data.json. hmm)

Rich-Harris avatar Nov 17 '22 17:11 Rich-Harris

This is working as designed — each page should have a single unambiguous URL, otherwise SEO suffers and things get weird with relative links. You can explicitly add the index.html to routes, like so...

-src/routes/my-route/+page.svelte
+src/routes/my-route/index.html/+page.svelte

...and /my-route/index.html will work (but /my-route won't). Does that solve your case?

I guess it solves my case, but it just feels weird... I get it that best practices dictate that you shouldn't explicitly use index.html in a URL in 2022, for SEO reasons or whatever, but svelte-adapter-static might be used to generate code for legacy static servers that may consider /my-route.html, /my-route and /my-route/index.html to be the same, as it used to be with static vanilla HTML. Especially since a index.html file actually exists.

In my personal case, I need to explicitly set index.html in the URL in order to pass query parameters to the page, which is used within an iframe. For some reason, https://myurl.com/my-route?foo=bardoesn't work, but https://myurl.com/my-route/index.html?foo=bar does.

Anyway, thank you for the reply.

TomFevrier avatar Nov 17 '22 18:11 TomFevrier