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

Opt-out of asset inlining - with SSR support #15986

Closed
4 tasks done
hyunbinseo opened this issue Feb 20, 2024 · 5 comments
Closed
4 tasks done

Opt-out of asset inlining - with SSR support #15986

hyunbinseo opened this issue Feb 20, 2024 · 5 comments

Comments

@hyunbinseo
Copy link
Contributor

Description

Allow individual static asset imports to opt-out from inlining.

The following SVG file is inlined in the build process.

<script lang="ts">
  import background from '$lib/static/background.svg';
</script>

<div style:background-image={`url("${background}")`}></div>

Currently, asset inline can only be disabled globally.

You can disable inlining SVG by setting the assetsInlineLimit option to 0. The default is 4096 (4KiB).

#14643 (comment)

Suggested solution

Utilize the explicit URL import syntax.

<script lang="ts">
  // Do not inline the SVG. Use the href value in the CSS.
  import background from '$lib/static/background.svg?url';
</script>

<div style:background-image={`url("${background}")`}></div>

Alternative

The new URL(url, import.meta.url) method exists, but it does not work in SSR.

This pattern does not work if you are using Vite for Server-Side Rendering, because import.meta.url have different semantics in browsers vs. Node.js.

https://vitejs.dev/guide/assets.html#new-url-url-import-meta-url

Additional context

Related issue and PR:

SvelteKit context:

  • The Node.js adapter does not cache files in the /static directory.
  • Use Vite's static asset import, which will set a cache header for 365 days.
  • Static files under 4 KiB are inlined, and this cannot be opted out per-file.

https://github.com/sveltejs/kit/blob/511126b51d4aaa770704491ff0890a76fa116205/packages/adapter-node/src/handler.js#L54-L56

Validations

@sapphi-red
Copy link
Member

Vite 5.1+ supports callback style build.assetsInlineLimit. You can filter individual files with it.

assetsInlineLimit: (file) => {
    return !file.endsWith('.svg');
}

@hyunbinseo
Copy link
Contributor Author

hyunbinseo commented Feb 20, 2024

@sapphi-red Thank you. Forgot to mention it in the issue body.

However, I am not sure if it is a friendly DX - especially for specific files.

const configuration = {
  build: {
    assetsInlineLimit: (file) => {
      const pathnames = [`${process.cwd()}/src/lib/static/background.svg`];
      if (pathnames.includes(file)) return false;
    },
  },
};

// vs

import background from '$lib/static/background.svg?url';

@bluwy
Copy link
Member

bluwy commented Feb 21, 2024

Related: #15454

@sapphi-red
Copy link
Member

The downside of using a query is the possibility of bundling a single file both as inlined and as non-inlined.

import backgroundUrl1 from './background.svg?non-inlined-url' // https://...
import backgroundUrl2 from './background.svg' // data:...

@sapphi-red
Copy link
Member

Closing as #15454 is merged.

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

3 participants