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

Could not to use relative asset URL #8342

Closed
mislam opened this issue Jan 5, 2023 · 7 comments
Closed

Could not to use relative asset URL #8342

mislam opened this issue Jan 5, 2023 · 7 comments

Comments

@mislam
Copy link

mislam commented Jan 5, 2023

Describe the bug

For my use case, I need the asset path to be relative (without a leading slash).

Why? In case of a Chrome Extension or a bundled Desktop App like Electron, the assets need to be loaded without serving from a web server. Thus requires the paths to be relative.

Currently, %sveltekit.head% produces absolute <link ...> such as:

<link rel="modulepreload" href="/_app/immutable/start-be880a54.js">
<link rel="modulepreload" href="/_app/immutable/chunks/index-7f3551f2.js">
<link rel="modulepreload" href="/_app/immutable/chunks/singletons-c1916556.js">

I need these links to be:

<link rel="modulepreload" href="_app/immutable/start-be880a54.js">
<link rel="modulepreload" href="_app/immutable/chunks/index-7f3551f2.js">
<link rel="modulepreload" href="_app/immutable/chunks/singletons-c1916556.js">

Just without the leading slashes.

Reproduction

Create a new SvelteKit app using npm create (as mentioned in the Getting Started page):

npm create svelte@latest my-app
cd my-app
npm install

Install adapter-static:

npm install -D @sveltejs/adapter-static

Edit svelte.config.js:

-import adapter from '@sveltejs/adapter-auto';
+import adapter from '@sveltejs/adapter-static';

Then added a new file: src/routes/+layout.ts:

export const prerender = true;

That worked! But if I use +layout.svelte instead of +layout.ts:

src/routes/+layout.svelte:

<script lang="ts">
  export const prerender = true
</script>

<slot></slot>

And then run npm run build, it complains that all routes must be fully prerenderable.

Logs

  @sveltejs/adapter-static: all routes must be fully prerenderable, but found the following routes that are dynamic:
    - src/routes/

  You have the following options:
    - set the `fallback` option — see https://github.com/sveltejs/kit/tree/master/packages/adapter-static#spa-mode for more info.
    - add `export const prerender = true` to your root `+layout.js/.ts` or `+layout.server.js/.ts` file. This will try to prerender all pages.
    - add `export const prerender = true` to any `+server.js/ts` files that are not fetched by page `load` functions.

    - pass `strict: false` to `adapter-static` to ignore this error. Only do this if you are sure you don't need the routes in question in your final app, as they will be unavailable. See https://github.com/sveltejs/kit/tree/master/packages/adapter-static#strict for more info.

System Info

npx envinfo --system --binaries --browsers --npmPackages "{svelte,@sveltejs/*,vite}"
  System:
    OS: macOS 12.6.2
    CPU: (8) x64 Intel(R) Core(TM) i7-6920HQ CPU @ 2.90GHz
    Memory: 1.22 GB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 18.12.0 - ~/.nvm/versions/node/v18.12.0/bin/node
    npm: 8.19.2 - ~/.nvm/versions/node/v18.12.0/bin/npm
    Watchman: 2022.10.10.00 - /usr/local/bin/watchman
  Browsers:
    Brave Browser: 108.1.46.144
    Chrome: 108.0.5359.124
    Firefox: 103.0.2
    Safari: 16.2
  npmPackages:
    @sveltejs/adapter-auto: ^1.0.0 => 1.0.0
    @sveltejs/adapter-static: ^1.0.1 => 1.0.1
    @sveltejs/kit: ^1.0.0 => 1.0.7
    svelte: ^3.54.0 => 3.55.0
    vite: ^4.0.0 => 4.0.4

Severity

Serious, and I could not work around it

Additional Information

No response

@benmccann
Copy link
Member

Sounds similar to #907 and #595

@Rich-Harris
Copy link
Member

Please don't write N/A in the reproduction section.

SvelteKit does use relative paths by default. The exceptions are a) you've specified an external asset path or b) you're rendering a fallback page:

if (options.paths.assets) {
// if an asset path is specified, use it
assets = options.paths.assets;
} else if (state.prerendering?.fallback) {
// if we're creating a fallback page, asset paths need to be root-relative
assets = options.paths.base;
} else {
// otherwise we want asset paths to be relative to the page, so that they
// will work in odd contexts like IPFS, the internet archive, and so on
const segments = event.url.pathname.slice(options.paths.base.length).split('/').slice(2);
assets = segments.length > 0 ? segments.map(() => '..').join('/') : '.';
}
/** @param {string} path */
const prefixed = (path) => (path.startsWith('/') ? path : `${assets}/${path}`);

I assume the latter applies in your case, but without a reproduction I'm just speculating.

@mislam
Copy link
Author

mislam commented Jan 6, 2023

Please don't write N/A in the reproduction section.

Updated the reproduction section.

SvelteKit does use relative paths by default. The exceptions are a) you've specified an external asset path or b) you're rendering a fallback page:
...
I assume the latter applies in your case, but without a reproduction I'm just speculating.

You guessed it right. My use case is to package the code into an Electron app. That's why I used static adapter with fallback to index.html. Not sure if I'm doing the right thing here. Since all assets will be packed locally, relative path is the only option for me.

@Rich-Harris
Copy link
Member

For an Electron app, I don't think you need to use fallback. The purpose of fallbacks is so that if you use a static webserver and the user hits a path like /foo/bar/baz, it can serve the fallback 200.html (or whatever) page and the app will work as an SPA. For 200.html to work equally well for /foo/bar/baz and /, the fallback must use absolute paths.

But in an Electron app you have a lot more control — you should be able to serve a regular index.html and go from there, I think?

@mislam
Copy link
Author

mislam commented Jan 9, 2023

Rich-Harris, I tried. This time I wanted a clean reproduction of this issue to nail it down to the dot. Please see the updated Reproduction section. This time no Electron, I just focused on getting adapter-static to work. This time npm run build doesn't work while using +layout.svelte instead of +layout.ts.

@benmccann
Copy link
Member

If you're trying to use Electron, you might find some of the existing resources from around the web to be helpful:

@mislam
Copy link
Author

mislam commented Jan 9, 2023

Solved by moving export const prerender = true from src/routes/+layout.svelte to src/routes/+layout.ts.

@mislam mislam closed this as completed Jan 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants