I am working on a new version of my website using sveltekit. I am using svelte 5 for context.
There is a page on my website that shows a bunch of screenshots from games I play. I have written a vite plugin to create low-res versions of images in order to load and show those blurred while the high res versions load in the background (it also crops images in a certain folder to remove the black bars). This means that I need to fetch images from two places, one from the low-res folder, and one from the main images folder. On the main page there are some static images, which are held inside the static/images and static/low-res folders, which work both in dev and prod. On the screenshots page, the images are held in src/lib/images/screenshots and have subfolders of cropped and low-res. I use import.meta.glob
to import all images from the main screenshots folder in order to get the name of each, then I pass through to my image component the imagePath (/src/lib/images/screenshots/cropped) and the low-res path (/src/lib/images/screenshots/low-res) as well as the image name. This works in development, showing the low res images while the high res ones load, but in production no images load as the url can not be resolved. I am aware that the src folder doesnt exist when the website is built, but I did think that sveltekit or vite would handle the imports properly, as in the end they just to to an img src.
Enviroment:
Node 22.9.0
npm 10.8.3
pnpm 9.12.1
IDE vscode
Deployer cloudflare pages
website url https://new.jazza.dev
github repo https://github.com/Jazza-231/new-website
Relevant packages
svelte
sveltekit
typescript
threlte
gsap
sharp
Code examples (only relevant parts, not all of the code)routes/screnshots - importing the images and getting the names - not working in prod
const images = import.meta.glob("$lib/images/screenshots/*.{png,jpg}", { eager: true, }); let urls: string[] = []; let names: string[] = []; for (const image in images) { if (Object.prototype.hasOwnProperty.call(images, image)) { let url = (images[image] as { default: string }).default; urls.push(url); } } urls.forEach((url) => { const split = url.split("/"); names.push(split[split.length - 1]); });
routes/screenshots - the image component usage
<Image imagePath="/src/lib/images/screenshots/cropped/" lowResPath="/src/lib/images/screenshots/low-res/" imageName={name} header="Test"/>
lib/Image.svelte - the image component
<img src={lowResPath + imageName} alt="Image for {header}" class="blur" bind:this={image}/><img src={imagePath + imageName} alt="Image for {header}" class="hidden" onload={loaded} bind:this={srcLoader}/>
routes/page.svelte - working example of image component, through bento component
const imagePath = "/images/bento/";const lowResPath = "/low-res/bento/";
<Bento header="Scratch Addons" {imagePath} {lowResPath} imageName="ScratchAddons.png" content="A collection of addons for the kids' coding website; Scratch." href="/projects/scratch-addons" area="a" />
I have tried multiple locations for the screenshots, including in the static folder, in the src folder, and ofc in the lib folder. All have their own problems with vite or js or sveltekit.I have also tried absolute urls, relative urls, svelte urls (when you use $lib for example), as well as import.meta.glob, new URL with import.meta.url, and normal imports.
None of these have worked in prod yet.
I am open to large code changes if they are well explained, and as I am new, any info on best practicies would be appreciated.