sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
17.97k stars 1.8k forks source link

Dynamic basepath #595

Closed Rich-Harris closed 1 year ago

Rich-Harris commented 3 years ago

Moving this here:

One blocking issue I've run into with the current Sapper is that I can't rewrite urls from various sites that we want to host a "whitelabel" version of our app on, because the basepath has to be set in stone at build time:

https://example.com/some-path/ <-- does not work https://subdomain.example.com/ <-- works fine

rather than host a different app for people who want to mount it under a subpath, ideally basepath could be a runtime concern. However I don't know if this is feasible, but it's worth considering.

Cool. For me it is to support ipfs website both when served through an ENS domain or through a gateway with ipfs/ base path for example, both url point to the same exact content : https://ipfs.io/ipfs/bafybeieeuq3av6jdys2q2zwhfv5hutcqejczr46wzjikd5vulfaxfi72r4/ https://jolly-roger.eth.link/ for the hash version, I have to compute at runtime the basepath since it is not possible to know the hash of an ipfs website at build time

https://ptb.discord.com/channels/457912077277855764/750388563354583071/771786495152357386

paths.base is baked into the app at build time. Changing this would likely need to be done in Vite: https://github.com/vitejs/vite/issues/2009

antony commented 3 years ago

Yeah - this is super critical from my perspective, we have an ever growing range of people who use our main site with branding, and they hate subdomains because it's arguably not as good for SEO. Sapper doesn't support using a sub-path as the root without a totally separate build and deployment.

Rich-Harris commented 3 years ago

Pretty sure we could make it an environment variable

blackshot commented 3 years ago

this is critical for deploying exported static files into github pages because generated urls for custom repos are https://{username}.github.io/{repository} without it assets will be fetched at root level instead of subpath

Rich-Harris commented 3 years ago

@blackshot in those cases, repository is known at build time. Just configure paths.base accordingly. This issue is about cases where the basepath isn't known at build time

blackshot commented 3 years ago

sorry, my bad. i didn't understand it well.

Rich-Harris commented 3 years ago

To recap discussion elsewhere, environment variables solve the white-labelling problem in cases where pages are being server-rendered, but they don't solve the problem in cases where there are no environment variables (e.g. prerendering). For applications like IPFS, we (apparently β€” I know nothing about IPFS) don't know the basepath until the app is running in the browser.

Presumably we could construct the basepath by subtracting the initial pathname from location.pathname...

<script type="module">
  import { start } from '../../_app/start-xyz123.js';
  const path = '/foo/bar/baz'; // known at render time
  const base = location.pathname.slice(-path.length);

  start({
    target: document.body,
    paths: { base, assets: base || '/.' },
    // ...
  });
</script>

...then if location.pathname is something like /basepath/foo/bar/baz then we know that base is /basepath without needing to include that information in the HTML. Feels brittle but as long as you trust that pages and assets end up in the expected place relative to each other then it ought to work perfectly.

Throwaway thought: this could be useful in the context of i18n, where the basepath is a language identifier like /de or whatever.

Rich-Harris commented 3 years ago

This is affected by the issue described in #1155

kayakyakr commented 3 years ago

Another use case that this breaks is when trying to launch a sveltekit app from a chrome extension. This is a big deal in a content script, especially, where it's trying to preload those links via the embedded page's url.

I'm actually skipping the generated page to run the start script directly, but the module preload still throws a bunch of errors, and all of the css fails to load.

I'm still working out exactly what needs to happen and if there's a workaround, but this is pretty much putting the kibosh on my dreams of running sveltekit from an extension.

wighawag commented 3 years ago

By the way the method @Rich-Harris you describe in your comment is exactly how sveltejs-adapter-ipfs handle it currently :

It inject similar code directly in the html and it works nicely : https://github.com/wighawag/sveltejs-adapter-ipfs/blob/d52856d230796e09e560e183b7b0ddb9d7e08482/lib.js#L115

There are other problem that need to be tackled with to be able to have a static website completely independent of the path it will be hosted on.

For example font generated css currently use absolute path : https://github.com/sveltejs/kit/issues/1477

wighawag commented 3 years ago

I updated my ipfs adapter repo with link to the various issues in svelte kit,

it describe what is missing in svelte-kit for proper support of ipfs (and other hosting platform that require basepath to be dynamic) : https://github.com/wighawag/sveltejs-adapter-ipfs

It currentl implements the solutions as a post-process steps and so it is currently very brittle.

I also setup a demo repo that uses the adapter succesfully : https://github.com/wighawag/sveltekit-ipfs-demo

KonradHoeffner commented 3 years ago

@blackshot in those cases, repository is known at build time. Just configure paths.base accordingly. This issue is about cases where the basepath isn't known at build time

But then I cannot do npm run dev anymore because I prepend base to my redirects and links and this breaks it on localhost.

johannesrave commented 3 years ago

My application is a prerendered site which is deployed on a webspace at my Uni. When I change the basepath to the subdirectory on that webspace where the app will be located, CSS works but the HTML links to the routes break (they link to root which 404's). When I leave out the basepath, CSS breaks. Also I'd like to be able to keep using yarn dev.

I guess a solution for me could be what @KonradHoeffner is doing plus somehow checking for dev vs. prod and then prepend base depending on that. It would be cool though if the whole thing was more or less location agnostic... I probably lack understanding why that is a daft idea, it's just what I expected going into the project.

antony commented 3 years ago

No its perfectly reasonable. I made a start but work got in the way. I hope to pick it up again as soon as I can.

eikaramba commented 2 years ago

When I change the basepath to the subdirectory on that webspace where the app will be located, CSS works but the HTML links to the routes break (they link to root which 404's).

I have the exact same problem now. i am just trying to deploy a svelte kit app with adapter-node to mydomain.com/svelteapp and unfortunately all links are broken. is this here the correct ticket however for that? because as far as i understand it, this ticket goes further and wants to fix dynamic basepath during rendering, whereas this problem i am facing is merely lack of considering the base path in the router when navigating.

johannesrave commented 2 years ago

I wanted to get the dev server and the uploaded build to work in the setup for my university-project. I'm checking for dev now with this env-variable, as 'dev' doesn't work in svelte.config.js, then setting base depending on that.

import adapter_static from '@sveltejs/adapter-static';
import preprocess from 'svelte-preprocess';
import path from 'path';

const dev = process.env.NODE_ENV == 'development';
const base = dev ? '' : '/path/on/server';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    preprocess: preprocess(),

    kit: {
        adapter: adapter_static({
            // default options are shown
            pages: 'build',
            assets: 'build',
            fallback: null
        }),
        target: '#svelte',
        paths: {
            base: base
        }
    }
}

export default config;

Then I import base from other components/pages and prefix my links with it. This works, if I remember to set it on all the links:

<script lang="ts">
    import { auth } from '$lib/stores.js';
    import { goto } from '$app/navigation';
    import { onMount } from "svelte";
    import { base } from '$app/paths'

    onMount(() => {
        if (!$auth) {
            console.log("Not authenticated, going back to login.")
            goto(base + '/login');
        }
    })

    // or like so:
    <RoundButton link={base + '/banking'} name={'SEND BUCKS'}/>
</script>

Like I said, I'm not sure I'm qualified really to discuss this stuff, but just saying this works for me if anyone else is looking for a workaround and finds this.

eikaramba commented 2 years ago

@johannesrave of course for programmaticaly invoking the navigation it works and is one workaround. however all static links like <a href="/test"> would either not work or need additional hacks like <a href="{base}/test"> - so possible yes, but not really maintainable or "sveltesque" IMHO :)

johannesrave commented 2 years ago

I absolutely agree, I'm just glad it's running for the moment :P

Also there are two things in this, I think. One being the svelte-kit basepath so CSS and stuff/assets are found, which is what you CAN set in paths.base, even though one needs to check for dev env manually. The other issue are links in the markup. Maybe in the workaround I could solve the second one better using a conditional <base>-tag in __layout instead of prepending base to every single page-link... playing with that now. Then it would be only the one manual path you have to maintain.

EDIT: Spent another few hours down that rabbithole. The <base>... it does nothing! I put <svelte:head><base href="{base}"></svelte:head> in __layout, looked at the generated HTML in the browser, and also tried editing it there. <base> is (reactively?) moved to the end of the <header>, and I assume, some other <base> generated from what it set in svelte.config.js supercedes it - so the links in markup still point to domain.tld when hovering (and clicking obviously) instead of domain.tld/base/path/.

When I manually move it to the top (in the browser inspector!) the links show up right on hover, including the correct domain path. When moving the element up in the generated html in build, it is moved towards the end of <header>again when the site is loaded, so something scripty is going on to move it there?

It's been pretty fruitless, and I'll stop trying to work on this at the root and just go with my silly prepended hrefs until someone qualified fixes this in a release.

davidberglund commented 2 years ago

Came here when realizing I need to prefix all URLs with '/static/' or replace '/./' with '/static/' for using SvelteKit builds with Python (with the Flask framework). I put static assets in static/static/ in the SvelteKit app dir to get those right at least (so those will resolve to mydomain.com/static/... after build). But I need to customize the other URLs for prod builds. I know this issue is about dynamically handling basepath during runtime, but hoping to at least have static basepath configurable at some point

DanMacDonald commented 2 years ago

Trying to deploy a SPA to arweave, similar to IPFS, having to prepend ./ to all my paths to allow hosting relative to a basepath and it's not entirely working...

Worth noting here, arweave is a protocol for permanent storage, once you upload a file it's there permanently. It provides the foundation for something called the 'permaweb'. Files are submitted with transactions whose transaction id is a hash of the transactions fields. The transaction id ultimately becomes the basepath when the file is hosted, but once you know what that id is, you can't go back and edit your files to include it without violating the hash. It's a chicken and egg thing. πŸ₯š πŸ”

So from a transaction id: l62soGCK7qbfDjoZ0zQDZjPp4zaZI5YlT_iURFfj5ZE you might end up with the following path...

https://s6w2zidarlxknxyohim5gnadmyz6tyzwterzmjkp7ckeiv7d4wiq.arweave.net/l62soGCK7qbfDjoZ0zQDZjPp4zaZI5YlT_iURFfj5ZE

...where the transaction id becomes part of the basepath.

It would be great to be able to host Svelte SPAs without having to specify a base path explicitly ahead of time to support the "developing permaweb SPAs on arweave" usecase. πŸ‘

Edit: I was able to use @wighawag 's sveltejs-adapter-ipfs to unblock myself. Saved my bacon so thanks for that! (I had some remaining relpaths to deal with but was able to handle it in user code)

Rich-Harris commented 2 years ago

not fully caught up on this thread but wanted to add a further thought: apps that expect the basepath to be something specific are liable to break when they're archived. The Wayback Machine has URLs like https://web.archive.org/web/20200331000251/https://www.yoursite.com/, and naturally that causes stuff to break. I've been bitten by this today (though not by a SvelteKit app).

If you're doing SSR that's not necessarily catastrophic β€” it means that the router won't fire, but hopefully at least your content and styles will behave correctly. But it'd be a hell of a lot better for future historians if client-side routers were designed with portability in mind.

pavelloz commented 2 years ago

I think, at least for the assets it is very important to be able to set the base path to CDN during runtime. In webpack case we are using https://github.com/agoldis/webpack-require-from and it is a huge help. When you have a template repo that you clone and then do a quick project from, deploy on a server and you do not know the CDN's host beforehand it saves a manual labor, writing docs for it and some brain power, because there is nothing to remember.

Keeping CDN url in the envs/package.json is suboptimal to say the least, especially when you have multiple environments to deploy to (qa, staging, prod), because you have to suddenly have 3 envs in your repo AND build three times to deploy to them. Which is a waste of CI time and dev time, on waiting (ergo, money).

Example from webpack usage is also a very concise one:

webpack.config.js

 new WebpackRequireFrom({
      variableName: 'window.__CONTEXT__.cdnUrl',
    }),

Template:

   <script>window.__CONTEXT__ = { cdnUrl: "{{ '' | asset_url }}" };</script>
antony commented 2 years ago

You can already set the cdn/assets url in sveltekit config. This is about basepath which relates to the path which the application itself runs from.

Setting things on the window object is fine for clientside but won't solve SSR, so the we pack solution you posted won't work for sveltekit. I'm not 100% sure how secure it is either - it strikes me that loading a malicious clientside app might be made trivial by overriding this variable?

KonradHoeffner commented 2 years ago

Why are absolute URLs even required in the first place? I am mainly not a frontend developer, but when I do create websites, I always use relative paths like import x from '../MyClass'; and I have never had a problem with that. This allows the same website to run locally from the browser over the file protocol, over a local webserver regardless of which root folder it is launched from, on the target domain and on GitHub pages all at the same time. Wouldn't that solve all those problems without requiring any kind of configuration?

pavelloz commented 2 years ago

@KonradHoeffner Im trying to use only relative urls as well, im pretty fresh to SvelteKit, still experimenting with outputs (im using static site generator adapter) and how it can be hosted on our stack, but i remember having issues with webpack (hence plugin usage - it tells webpack where to look for async loaded chunks). Maybe im raising alarm over nothing and it will turn out to be unnecessary

@antony no security issues there. I dont know what "a malicious clientside app" is/could be, but if it had access to the website JS context changing asset variable is the least of concerns of the user at this point ;)

Apparently webpack even has native setting for it, not need to use plugin as i did: https://github.com/webpack/webpack/issues/443#issuecomment-54113862 This kind of tells me there is a need for those kinds of features - runtime vs build time, to not build 10 versions if you want to deploy the same frontend to 10 different environments with different cdn hosts.

antony commented 2 years ago

We aren't talking about paths used at development time. We are talking about the url that the html loads the javascript assets from and considers the browser "Base url". Right now you can't serve the same built application at https://example.com and https://example.com/some/path - it just won't work.

antony commented 2 years ago

Where to load chunks from can be defined in kit config. But the application still needs to know it's own path. That can't be relative - yet.

I'll try to build an example as soon as I get a chance. It will help both with explaining the issue, and with working on a solution.

antony commented 2 years ago

I dont know what "a malicious clientside app" is/could be

Suppose I can pass an unsanitised variable to your app. A line of js which would execute. I can spend a long time developing a worthwhile exploit based on your existing code, or, I can trivially override a variable to point to my own copy of your app's clientside code.

Both are bad but one is significantly worse.

I don't know how normal it is to define the app's path as a global variable, but it seems like a very easy exploit to me, exploitable with a very commonly made mistake.

pavelloz commented 2 years ago

@antony Changing variable means having JS access to the site in its context. Having that situation = game over. Not because CDN path can be changed, but because EVERYTHING can be changed, added, stolen, downloaded and executed. ;)

pavelloz commented 2 years ago

Ok, after couple hours of trying to make it work i think the resulting issue is the usual one, described above.

  1. Im generating static site.
  2. I want to use assets/async chunks from different domain
  3. Even if i put images in static/ and hardcode paths (like recommended in one of GH issues), JS loads them from relative path to app origin (not cdn).

Test.svelte

<img src="/assets/images/awards/2021/ISTC.png" />

Resulting html is correctly, the same: <img src="/assets/images/awards/2021/ISTC.png">

So i ran find/replace and deployed again, to use CDN version, so html looks now: <img src="https://uploads.staging.oregon.platform-os.com/instances/7043/assets/images/awards/2021/ISTC.png">

Now browser tried to load CDN version, then version from relative path from JS (doubling requests). Not always both are downloaded.

image

What im trying to achieve, and probably not only me, is to avoid loading assets from the domain with cookies, with no CDN. Thats why i would like to setup cdn path in runtime for dynamic assets, including images.

I would love to run my find/replace script also on JS files, but during build time i do not know CDN url. The fact that i have to resort to those kinds of hacks points into a hole in functionality that is IMO pretty standard nowadays.

PS. And maybe this is completely different issue as @antony suggested here https://github.com/sveltejs/kit/issues/595#issuecomment-998043219 :)

benmccann commented 2 years ago

There are a ton of comments here. I've updated the issue description to clarify that this would likely need to be handled in Vite: https://github.com/vitejs/vite/issues/2009. Anyone who's interested can take a look at sending a PR for that issue

wighawag commented 2 years ago

Hi, is there any update on this issue ?

I see that it is not in the list of things to go for an 1.0 release (https://github.com/sveltejs/kit/issues/2086)

Just my opinion but it feels like this problem need to be addressed early as it touches on several assumption that might be harder to rectify later.

I am currently using a fork of static-adapter here : https://github.com/wighawag/sveltejs-adapter-ipfs and it had to perform some ugly post-processing step to do what I need.

Happy to describe in more details the requirement if needed.

As I mentioned here : https://github.com/sveltejs/kit/issues/595#issuecomment-842634581 I gathered a list of things needed in svelte-kit for proper support of ipfs (and other hosting platform that require basepath to be dynamic) here : https://github.com/wighawag/sveltejs-adapter-ipfs

stalkerg commented 1 year ago

@wighawag I suppose it's have already support. You should just try relative paths in base. Probably we can close this issue.

wighawag commented 1 year ago

Hi @stalkerg I just tried porting my app to use latest vite + svelte kit and it does not seems like it solve all the issue with dynamic basepath

Maybe I did not set all the options required ? If so which are they ?

As I got it setup, the adapter-static generate demo.html instead of demo/index.html for example and I have issues with CSS.

You can try my app with the latest svelte-kit in this branch : https://github.com/wighawag/jolly-roger/tree/latest-svelte-kit

It is a mono repo but you can try the web part only by doing the following:

generate the build

git clone git@github.com:wighawag/jolly-roger.git
cd jolly-roger
git checkout latest-svelte-kit
pnpm i
pnpm web:build staging

serve it via an ipfs gateway emulator:

pnpm web:serve
stalkerg commented 1 year ago

@wighawag yeah, vite side it's only one piece in the puzzle. https://github.com/sveltejs/kit/labels/paths.base I think issue #4250 is more relevant to your case.

wighawag commented 1 year ago

I tried again, reading the whole svelte-kit doc from a to z and that's where I am stuck:

I cannot set paths: { base: './' } as it is not allowed and if I set paths: { base: '' } I get issues with css, js files being refered as /_app even if the hosting is done in a sub folder.

I updated the branch mentioned above to reflect that

benmccann commented 1 year ago

1.0.0-next.419 was released to make better use of relative asset paths: https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md#100-next419

It will now use ./ by default:

https://github.com/sveltejs/kit/blob/7b305af71d1abbe9913b076a57bf59ed0c1e0e31/packages/kit/src/vite/build/utils.js#L95

That being said, this issue is still open :smile: So I wouldn't expect it to work just yet...

wighawag commented 1 year ago

@benmccann oh ok, I was confused with @stalkerg comment, I thought it was already supposed to work :)

Just tried the latest and the CSS and js works for my demo. Navigation does not work, but I might have added some custom stuff. I ll report back

wighawag commented 1 year ago

Ok, looking further, there seems to be indeed issue with navigation

<a href="" /> 
<a href="demo/" /> 

will always point to / and /demo/ respectively`

Also using import {base} from '$app/paths'; base is always the empty string, even when the web page is fetched from a sub folder.

atdiar commented 1 year ago

Just lightly thinking about this, how does it relate to the information in the HTML that's being served? I mean the <base> tag if present? That should be present and can be retrieved via Node.baseURI ? Shouldn't the host inject the base to make sure the links are still valid somehow, such as in the case of the waybackmachine?

Or is this the part that one may want to insert dynamically during page rendering?

DanMacDonald commented 1 year ago

Quite disappointed to see this issue get moved to post-1.0 πŸ˜”

yourcharlie23 commented 1 year ago

Hope this will be prioritised among all.

DanMacDonald commented 1 year ago

Unfortunately it doesn't seem like the incentives for Svelte SPA devs and Vercel are well aligned. Vercel operates an edge network that enables server side rendering. If SvelteKit has a really good story around building SPAs, from Vercel's perspective, all it does is provide a means for apps to migrate away from Vercel's services.

The missed opportunity here is that there is an audience of developers that are building decentralized applications to deployed to Arweave, IPFS, or other decentralized storage protocol where SSR is not a possibility. They are not users of Vercel's services (nor is it an option for them to be) but would be passionate supporters of Svelte in their respective domains.

stalkerg commented 1 year ago

@DanMacDonald team does not have enough resources; many of my issues are also in post-1.0 now. I suppose it's also my issue, I mean, I do have not enough time to make an excellent PR to cover my cases (but I can).

Anyway, I believe any PRs to solve this issue will be welcomed.

benmccann commented 1 year ago

There's no grand conspiracy here. Myself and the majority of the maintainers don't work at Vercel. There's ~350 open requests with 166 additional filed each month, so it's just that there's no guarantee we'll address the one that you happen to be most interested in amongst all the various issues that are out there as there's lots for us to keep up with. But PRs are welcome!

I am doing a bit of base path fixing at the moment and just sent a few fixes in addition to some base path fixes in vite-imagetools as well. This is one of the more advanced use cases, but we're getting more of the basics working now.

@wighawag I think https://github.com/wighawag/sveltejs-adapter-ipfs#readme is a bit outdated. If you could update sveltejs-adapter-ipfs to SvelteKit 1.0 and let us know what is still required that would be helpful (https://github.com/wighawag/sveltejs-adapter-ipfs/issues/10)

The assets are now referenced via relative path which seems like most of what was needed here: Screenshot from 2023-01-23 15-36-27

People are talking about quite a few different things in the comment thread here and it's gotten really hard to follow. I'm not exactly sure what's left to do, but I think the main change that's left is to do something like Rich mentioned here: https://github.com/sveltejs/kit/issues/595#issuecomment-809859449.

netfl0 commented 1 year ago

@blackshot in those cases, repository is known at build time. Just configure paths.base accordingly. This issue is about cases where the basepath isn't known at build time

I have the use case where it is not known at build time.

atdiar commented 1 year ago

In that case, I think it should be made available in the html (via the base tag) by whoever deploys the site and the framework should pick it up.

The way to pick it up is probably not by looking up the presence of <base> but simply getting the value of any node's Node.baseURI property on first request.

Which means in the example of the waybackmachine, they should make sure to modify/include the proper base before serving the html.

Am I mistaken?

wighawag commented 1 year ago

@benmccann Thanks for looking into it.

I did not yet found the time to update the ipfs-adapter for 1.0 but I just got the basic demo setup with an ipfs node emulator to showcase the issues.

https://github.com/bug-reproduction/svelte-kit-static-ipfs

Note though that this only highlight some of the issues as more complex scenario will likely exhibit more

rmarscher commented 1 year ago

For anyone struggling to find a workaround, I've had a little luck with using the static adapter and an empty base path. I can't get sveltekit's routing to work, but I can use a different client-side router.

In svelte.config.js (among other config settings) -

{
  kit: {
    adapter: staticAdapter(),
    paths: { base: '' }
  }
}

and in the outer +layout.ts

export const prerender = true;
export const trailingSlash = 'always';

With IPFS, the base folder name is the "content identifier" and based on a hash of the site contents. So you don't know it until after build. But... you do know that it is going to be one-level deep and follow a certain pattern.

I can use a regex pattern in my top level layout to extract the base path from the window.location and then use that to set up the client-side routing.

Maybe an adapter could do something similar with a regex pattern and get sveltekit's router working. Maybe it could inject a top-level runtime request handler that determines the base path and makes it available in $app/paths/base. Maybe it's more complicated than that though.

[Edit: some of the ideas in #8559 around setting base combined with optional route parameters / rest parameters seem like they could solve this use case and allow using sveltekit routing]

wighawag commented 1 year ago

hi @rmarscher, thanks for chiming in

I just tried adding paths: { base: '' } in the demo just posted above (https://github.com/bug-reproduction/svelte-kit-static-ipfs) but the issues mentioned there remain.

Re adapter, have a look at the adapter I created here : https://github.com/wighawag/sveltejs-adapter-ipfs

It is now quite old and might be outdated to work with v1 but it perform the IPFS base path extraction you mention and inject it. My next step is to figure out what of the processing step I can remove now that svelte-kit is in v1.

wighawag commented 1 year ago

Just some update after trying to get sveltejs-adapter-ipfs works with v1

While I can continue to inject the base at runtime and have routing works with IPFS, I get issues with +page.ts load function / +server.ts GET (which works fine with basic adapter-static and prerender), so this seems to be something to also consider when handling dynamic base path. Planning to update the demo to add this server load function (which I normally use for my statically generated blog) to add to the requirements the solution we want to come up with should support

EDIT:

I updated the demo to showcase the issue with +server.ts/+page.ts pre-rendered data : https://github.com/bug-reproduction/svelte-kit-static-ipfs

I think this demo cover most of the issues. I ll try to isolate more if I can find (I tried the service worker and seems that sveltekit v1 handles them better now, even with the builtin registration)

I could try to get around the issues again with my sveltejs-adapter-ipfs but it would be a lot better to have that properly handled in svelte-kit itself.

Let use this demo as a first benchmark to achieve.

you can play with it here by the way:

Work fine when on the root: https://bafybeia5gowaldvs5mwxdr2wbq7a2ssrwjsapkevy5xlmn2khu3luczkjm.ipfs.dweb.link/

Does not work on a path: https://cloudflare-ipfs.com/ipfs/bafybeia5gowaldvs5mwxdr2wbq7a2ssrwjsapkevy5xlmn2khu3luczkjm/