I have a Vite 4 project that uses vanilla JS & no frameworks. When I reference an asset using CSS url()
, it throws a 404 error. The path works fine in HTML img
src. I saw the answer for Vue but don't know how it applies to my project without a framework. Merely importing an asset from the index.js
file changes nothing.
_search-input.scss
.search-input {
width: 100%;
background-image: url("../../assets/icons/search.svg");
}
Index.js:
import "./styles/index.scss"
console.log("index file")
Project structure:
├── src/
│ ├── assets/
│ │ └── icons/
│ │ └── search.svg
│ ├── styles/
│ │ ├── ponents/
│ │ │ └── _search-input.scss
│ │ └── index.scss
│ └── index.js
└── index.html
I removed a single ../
from the path and now the image loads. However, isn't ../assets/icons/search.svg
an invalid path? From search-input.scss
I'm supposed to go up two levels to get to src/
and then reach assets
. My IDE also plains that this path can't be resolved. Why does this work? What is this path relative to?
I have a Vite 4 project that uses vanilla JS & no frameworks. When I reference an asset using CSS url()
, it throws a 404 error. The path works fine in HTML img
src. I saw the answer for Vue but don't know how it applies to my project without a framework. Merely importing an asset from the index.js
file changes nothing.
_search-input.scss
.search-input {
width: 100%;
background-image: url("../../assets/icons/search.svg");
}
Index.js:
import "./styles/index.scss"
console.log("index file")
Project structure:
├── src/
│ ├── assets/
│ │ └── icons/
│ │ └── search.svg
│ ├── styles/
│ │ ├── ponents/
│ │ │ └── _search-input.scss
│ │ └── index.scss
│ └── index.js
└── index.html
I removed a single ../
from the path and now the image loads. However, isn't ../assets/icons/search.svg
an invalid path? From search-input.scss
I'm supposed to go up two levels to get to src/
and then reach assets
. My IDE also plains that this path can't be resolved. Why does this work? What is this path relative to?
http://localhost:5173/assets/icons/search.svg
. When I removed a single ../
, the image loaded with the URL http://localhost:5173/src/assets/icons/search.svg
. I edited my post, not sure why it works.
– semi_92
Commented
Jan 23, 2023 at 16:57
_search-input.scss
is a partial loaded from index.scss
file. Could this be issue related to how SASS loads partials and resolves path?
– semi_92
Commented
Jan 24, 2023 at 13:05
It is difficult to understand what the problem is without the source code. I had a problem when building projects. I created subdirectories in the dist folder through vite.config for styles, pictures. Used build.rollupOptions.output.assetFileNames. For this reason, paths to images and fonts were not correctly created in css. This is due to the settings of the vite itself.
I searched for a long time how to fix this and found an experimental parameter that helped me solve the problem.
Advanced Base Options
Here is my piece of code that helped me.
With this function, I find the file in which I need to edit the paths and change them. The interface of the function is well described. It is not clear what exactly needs to be returned, but in theory it should be the path to the file.
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
base: '',
plugins: [react()],
server: {
open: true,
},
build: {
rollupOptions: {
output: {
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: function ({ name }) {
if (/\.(gif|jpe?g|png|svg)$/.test(name ?? '')) {
return 'assets/img/[name]-[hash][extname]';
}
if (/\.css$/.test(name ?? '')) {
return 'assets/css/[name]-[hash][extname]';
}
if (/.(png|woff|woff2|eot|ttf)/.test(name ?? '')) {
return 'assets/fonts/[name]-[hash][extname]';
}
// default value
// ref: https://rollupjs/guide/en/#outputassetfilenames
return 'assets/[name]-[hash][extname]';
},
},
},
},
// Функция которая поможет решить проблему путей
experimental: {
renderBuiltUrl: function (filename: string, { hostId, hostType, type }: { hostId: string, hostType: 'js' | 'css' | 'html', type: 'public' | 'asset' }) {
if (type === 'asset') {
if (hostType === 'css') {
const stringRemove = 'assets';
const stringLength = stringRemove.length;
const stringPesence = filename.indexOf(stringRemove);
if (-1 !== stringPesence) {
console.log('..' + filename.substring(stringLength));
return '..' + filename.substring(stringLength);
}
}
}
}
},
})
this worked for me
.app-bg {
background: url("@/assets/background1.jpg");
background-size: cover;
}
as I understand it, all paths to image files must be specified relative to the root sass file in which other sass files are piled.
./assets/icons/icon.svg in your case
CSS url() paths are relative to the current css location, in contrast to HTML img src which is not relative to the current path.
Maybe try to add another ../
to your css path.