Skip to content

${base}/foo -> resolve('/foo')Β #13840

@Rich-Harris

Description

@Rich-Harris

Describe the problem

SvelteKit prioritises portability β€” if you have something like this...

<script>
  import { base } from '$app/paths';
</script>

<a href="{base}/about">about</a>

...but you don't know the base path at build time (for example because you're using IPFS), it doesn't matter because the default behaviour is to make base relative during server rendering. So the markup above will result in the following HTML if it's rendered when you visit /...

<a href="./about">about</a>

...but this, if rendered when you visit /foo/bar/baz:

<a href="../../about">about</a>

To make this work, we set the value of base immediately before rendering, based on the URL of the page being rendered, and unset it immediately afterwards. But this only works because SSR in Svelte is synchronous.

In future, it will become necessary for SSR to be async. But that means that base could be read at a time when we don't control its value.

Describe the proposed solution

To fix this, we need to to use a function instead, so that we can use AsyncLocalStorage to determine the URL currently being rendered:

<a href={resolve('/about')}>about</a>

This would be a sibling to resolveRoute but without the parameter substitution or the possibility of type safe paths (which we still need to take advantage of).

For assets, we could have asset(url):

<img alt="potato" src={asset('/potato.jpg')} >

I propose adding these APIs to $app/paths now, and deprecating base and assets in v3 for removal in v4.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions