Opens an external site in a new window
Mental Health Awareness Month
“Community”
RODNEY LAB
  • Home
  • Plus +
  • Newsletter
  • Links
  • Profile
RODNEY LAB
  • Home
  • Plus +
  • Newsletter
  • Links

SvelteKit Dynamic Image Import: Add Images to Templates # SvelteKit Dynamic Image Import: Add Images to Templates #

blurry low resolution placeholder image SvelteKit Dynamic Image Import
  1. Home Rodney Lab Home
  2. Blog Posts Rodney Lab Blog Posts
  3. SvelteKit SvelteKit Blog Posts
<PREVIOUS POST
NEXT POST >
LATEST POST >>

SvelteKit Dynamic Image Import: Add Images to Templates #

Updated 3 years ago
5 minute read
Gunning Fog Index: 8.8
4 comments
Content by Rodney
blurry low resolution placeholder image Author Image: Rodney from Rodney Lab
SHARE:

✨ Introduction #

Let’s start by defining what we mean by SvelteKit dynamic image import by looking at a use case. We’ll then run through how to use Vite’s dynamic import functionality to help us out.

Before we start, I should mention that we are not talking about regular addition of images to a SvelteKit site. For example, if you write a Svelte component specifically for a given page. Let’s say an About Us page on a company site. If you know at the time you write the component exactly which image will be included on the page, then you probably want to be looking at the article on adding responsive, Next-Gen images in SvelteKit using vite-imagetools.

Here we are looking at cases where the page might be rendered by a template. That template might be responsible for rendering several pages, and each of those pages may well have a different image in the browser. This is the case even though they all come from the same template. An example might be an online store. You could have a template for product pages. Each individual product page can be created by the same template, but will probably include an image of the actual product it is referring to. This is exactly the case we are looking at here. Now you know what this is all about, let’s tackle the problem!

🖋 Example use Case #

We’ll look at a blog site as our example here. Our template will be able to render any blog post on our site. However, to improve user experience and ace Search Engine Optimization, we decide to add a different featured image to each blog post. We also want to use responsive images, with placeholders, to reduce cumulative layout shift. Finally, we want to cache and have links for images used in Search Engine Optimization (SEO) metadata. Let’s summarize our needs:

  1. Responsive images, in Next-Gen formats with placeholders to reduce Cumulative Layout Shift.
  2. We have a way to specify which image we will use on each page, but need the template to be able to render an arbitrary image.
  3. Want to use vite-imagetools to do heavy lifting in generating responsive image data.
  4. Let’s try to motivate a solution next.

    🗳 Poll #

    Which image plugin do you currently use for new SvelteKit projects
    Voting reveals latest results.

    🧑🏽‍🎓 SvelteKit Dynamic Image Import Problem #

    With vite-imagetools, you can generate a source URL just by importing an asset already saved within the project. As an example, the SvelteKit code might look like this:

        
    import featuredImageSrc from '$lib/assets/about/company-headquarters.jpg';

    We could add this code to an about page, for example, though going back to our blog use case, we would need a way to specify the image dynamically. You might already know that dynamic imports are possible with SvelteKit. This functionality is provided by Vite. Examples are:

        
    const modules = import.meta.glob('./dir/*.js')
    const data = await import(`../lib/assets/blog/${office}/index.json`);

    You might include the second example in a template file, defining office in an import.

    These work in the general case, though I had issues importing an image using vite-imagetools with a dynamic variable (no issues at all if we use a static path). Here is an example of the dynamic variable case:

        
    // WOULD NOT WORK
    const src = await import(`../lib/assets/blog/${slug}/${featuredImage}.jpg`;

    Interestingly, the following worked fine (importing a JavaScript file dynamically, rather than an image):

        
    imageData = await import(`../lib/assets/blog/data/${slug}.js`

    🧑🏽‍🎓 SvelteKit Dynamic Image Import Solution #

    I can smell a potential solution to the SvelteKit dynamic image import problem! We can create one of these files for each blog post and in the file generate the image data as usual. For example, add something like this to the data file:

        
    import meta from '$lib/assets/blog/post-one/featured-image.jpg';
    const { src, width } = meta;
    const data = {
    src,
    width
    }
    export { data as default };

    The downside here is that we have to write one of these files for each blog post. That might be quite onerous to do manually. However, we could create a script to generate these files, one for each blog post. On top, we could include extra data like low resolution image placeholders as well as SEO images, generated in our script. The script can run before every build, though in reality only needs to be changes on adding a new blog post or changing the blog images.

    Here is an example blog post image data file generated using such a script:

    Example generated file — click to expand code.
    Example generated file
    javascript
        
    import meta from '$lib/assets/blog/best-medium-format-camera-for-starting-out/best-medium-format-camera-for-starting-out.jpg?w=672&as=meta:height;src;width';
    import srcsetwebp from '$lib/assets/blog/best-medium-format-camera-for-starting-out/best-medium-format-camera-for-starting-out.jpg?w=1344;672&format=webp&as=srcset';
    import srcsetauto from '$lib/assets/blog/best-medium-format-camera-for-starting-out/best-medium-format-camera-for-starting-out.jpg?w=1344;672&jpeg&as=srcset';
    import ogImage from '$lib/assets/blog/best-medium-format-camera-for-starting-out/best-medium-format-camera-for-starting-out-open-graph.jpg';
    import ogSquareImage from '$lib/assets/blog/best-medium-format-camera-for-starting-out/best-medium-format-camera-for-starting-out-open-graph-square.jpg';
    import twitterImage from '$lib/assets/blog/best-medium-format-camera-for-starting-out/best-medium-format-camera-for-starting-out-twitter.jpg';
    const { height, src, width } = meta;
    const data = {
    slug: 'best-medium-format-camera-for-starting-out',
    alt: 'Photograph of a Hasselblad medium format camera with the focusing screen exposed',
    width,
    height,
    src,
    sources: [
    { srcset: srcsetwebp, type: 'image/webp' },
    { srcset: srcsetauto, type: 'image/jpeg' },
    ],
    dominantColour: '#484848',
    placeholder:
    'data:image/jpeg;base64,/9j/2wBDAAwREhMUFBUUFBofGhUaHiIcGhohKC4jJB4hMzg/PTouKC5CRFpMPi5XRTc3VmBRVlpgZmRkQklveXFmeFtlaWf/2wBDAQgMDQwNDw8PDxFgEBIaVmBaYFpgY2NjY2BjYGBiY2NjY2NjY2NjY2NjY2JjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAHAAoDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAIF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAwX/2gAMAwEAAhADEAAAAM+Cev8A/8QAHBABAAEEAwAAAAAAAAAAAAAAAQIAAxMhEZGh/9oACAEBAAE/AM5u2kZDIkS48rMmtnTX/8QAFhEBAQEAAAAAAAAAAAAAAAAAAQIA/9oACAECAQE/AKtkkDf/xAAXEQEAAwAAAAAAAAAAAAAAAAABABEh/9oACAEDAQE/AHKZ/9k=',
    ogImage,
    ogSquareImage,
    twitterImage,
    };
    export { data as default };

    Using a script, if we decide we want to use AVIF images instead of WebP or change our image widths, it is pretty easy to regenerate the data files. Likewise, if we decide to go for a plain, dominant colour placeholder instead of the low resolution one. You can see a full working example in the SvelteKit Blog MDsveX starter on the Rodney Lab GitHub page .

    🙏🏽 Feedback #

    Have you found the post useful? Do you have your own methods for solving this problem? Let me know your solution. Would you like to see posts on another topic instead? Get in touch with ideas for new posts. Also, if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a few dollars, euros or pounds, please consider supporting me through Buy me a Coffee.

    Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via @askRodney on Twitter and also askRodney on Telegram . Also, see further ways to get in touch with Rodney Lab. I post regularly on SvelteKit as well as other topics. Also, subscribe to the newsletter to keep up-to-date with our latest projects.

Thanks for reading this post. I hope you found it valuable. Please get in touch with your feedback and suggestions for posts you would like to see. Read more about me …

blurry low resolution placeholder image Rodney from Rodney Lab
TAGS:
SVELTEKIT

Likes:

Likes

  • Morgan profile avatar
  • Webjeda 🛹 profile avatar
  • TSR Codes profile avatar
  • Zuri profile avatar
  • flease profile avatar
  • Edan Ben-Atar 🐒 profile avatar
  • Svelte Society 🧡 profile avatar
  • Ryan Arpe profile avatar
  • Richard profile avatar
Likes provided by Mastodon & X via Webmentions.

Related Posts

blurry low resolution placeholder image Svelte CSS Image Slider: with Bouncy Overscroll

Svelte CSS Image Slider: with Bouncy Overscroll

sveltekit
<PREVIOUS POST
NEXT POST >
LATEST POST >>

Leave a comment …

Your information will be handled in line with our Privacy Policy .

Comments

  • Rar9

    Im new to the svelte world and looking for a faster front end to my drupal cms Would this js provide me the avif/webp/jpg images so all browsers are happy to use the best images. As images are of different content and sizes, would i just need this js once or multiple times? Just thinking of gatsby images

    4 years ago
    • Rodney

      Hi, thanks for reaching out. It's a little more manual than Gatsby images, that said, it is normally image width which matters when creating responsive images... you check the window width and sizes attribute based on that. So different input sizes will probably be OK, just make sure your input images are big enough to support all the sizes you want to use. Alternatively you may be able to get Drupal to generate the images for you, I know there is something similar with Wordpress.
      4 years ago
  • Richard

    Would it be possible to have a simpler example? I'm finding it hard to go through the repo and make sense of it, much less get it to work for me.

    3 years ago
    • Rodney

      Hi Richard, thanks for reaching out. I’d be happy to help, could you give a little detail on what you would like to acheive? Add an issue on the GitHub repo or reach out in the #rodney Matrix Element chat if that makes it easier to explain this.
      3 years ago

Ask for more

1 Nov 2022 — Astro Server-Side Rendering: Edge Search Site
3 Oct 2022 — Svelte eCommerce Site: SvelteKit Snipcart Storefront
1 Sept 2022 — Get Started with SvelteKit Headless WordPress

Copyright © 2020 – 2025 Rodney Johnson. All Rights Reserved. Please read important copyright and intellectual property information.

  • Home
  • Profile
  • Plus +
  • Newsletter
  • Contact
  • Links
  • Terms of Use
  • Privacy Policy
We use cookies  to enhance visitors’ experience. Please click the “Options” button to make your choice.  Learn more here.