Where to put images with SvelteKit - image

I have been using Svelte for a little while and now I have switched to SvelteKit so I can add multiple pages. I want to add some images to my site but I don't know where to put them. In Svelte I would just put them in public/images but there is no public folder with SvelteKit (I set it up with npm init svelte#next my-app if that matters). Would I put them in static?
Thanks!

I added the images in static/images and referenced them with src="/images/photo.jpg" like #b2m9 said and it works perfectly.

I recommend putting images under src/lib, not static. For example you could make a src/lib/images or src/lib/assets folder and put them there.
The reason is performance:
For files imported from anywhere under src, at compile time Vite adds a hash to the filename. myImage.png might end up as myImage-a89cfcb3.png. The hash is based on the image contents. So if you change the image, it gets a new hash. This enables the server to send a very long cache expiration to the browser, so the browser can cache it forever or until it changes. It's key-based cache expiration, which IMO is the best kind: cached exactly as long as it needs to be. (Whether the server actually sends the right caching headers in the response may depend on which SvelteKit adapter you use and what host you're on.)
By contrast, images under static don't have a hash added to their name. You can use the static directory for things like robots.txt that need to have a specific filename. Since the filename stays unchanged even if its contents change these files by necessity end up having a cache-control value that includes max-age=0, must-revalidate and an etag, which means even if the browser caches the image it still has to make a server round-trip to validate that the cached image is correct. This slows down every image on your site.
Usage:
When putting images under src/lib, you reference them like this:
<script>
import img from '$lib/images/img.png';
</script>
<img src={img} alt="Image" />
I recommend simplifying by adding svelte-preprocess-import-assets to your project, which automates the process of importing images and cleans up your code. You wrote the following and it generates the code above:
<img src="$lib/images/img.png" alt="Image" />

As Sveltekit uses Vitejs, there is a easy solution mentioned in Vitejs official web site (Click Here).
First inside the script tag :
<script>
const imgUrl = new URL('./img.png', import.meta.url).href
</script>
then inside your Image tag just use that variable,
<img src="{imgUrl}" alt="" />
or,
<div class=" h-screen w-full" style="background-image: url('{bgUrl}') ;">
</div>
You can import static images from any relative path.

there is also svelte-image.
"Svelte image is a pre-processor which automates image optimization using sharp.
It parses your img tags, optimizes or inlines them and replaces src accordingly. (External images are not optimized.)
Image component enables lazyloading and serving multiple sizes via srcset.
This package is heavily inspired by gatsby image.
Kudos to #jkdoshi for great video tutorial to Svelte Image."
-https://github.com/matyunya/svelte-image

Related

How can I present a different next/Image based on the user's preferred color scheme?

I'm trying to use a next/image instead of a regular img tag in the code below. With the regular <img> tag, the following achieves exactly what I'm looking for:
<div>
<picture>
<source
srcSet="https://via.placeholder.com/100/333333/ffffff.png"
media="(prefers-color-scheme: dark)"
/>
<img
src='https://via.placeholder.com/100/dddddd/000000.png'
width='100px'
height='100px'
alt='Placeholder image'
/>
</picture>
<p>Change your OS or browser's preferred color scheme to see a different image.</p>
</div>
Indeed, when I set my OS (or browser) to the dark theme, I get a dark image, and vice-versa for the light theme.
However, if I try the same thing with a next/image, I just get the light-themed image every time… I can't put this into a snippet because next/image requires a Next.js server, but here is the code that I'm using, which, in my tests, is backed by a Next.js development server with the appropriate image-related settings configured in next.config.js:
// pages/test.js
import Image from 'next/image'
export default function MyWebPage () {
return (
<div>
<picture>
<source
srcSet="https://via.placeholder.com/100/333333/ffffff.png"
media="(prefers-color-scheme: dark)"
/>
<Image src='https://via.placeholder.com/100/dddddd/000000.png' width='100px' height='100px' alt='Placeholder image' />
</picture>
<p>You can change your OS or browser's preferred color scheme, but you'll always see the light-theme image.</p>
</div>
)
}
Here I never get the dark-themed image, unfortunately.
Theories:
Perhaps next/image doesn't interact with the <picture> tag exactly the same way as <img>? But I'm not finding anything online about using next/image with the <picture> tag…
Perhaps I should be providing this media-query-dependant source set in a different way when using next/image? But, I'm not finding any media attribute in the next/image docs…
Question:
How can I change the src of my next/image based on the user's preferred color scheme?
Non-solutions:
I could put 2 images on the page and use display: none on one of the two as a function of the user's preferred color scheme, but I'm hoping to find a solution that doesn't require so many duplicate images all over the place, which incurs a (small) performance penalty and makes the code that much harder to maintain, or that much more complex if a helper component is created.
I could change the src using Javascript when the page loads, but this would result in a flash of incorrectly styled content and generally does against my objective of having my page fully server-rendered and compatible with browsers where Javascript is turned off.
I could use cookies to let the server know about a user's color scheme preference and render the page consequently, but this would not work for the very first visit and comes with the requirement to include a cookie bar to inform the user of the reasons behind the use of cookies, as well as a way to opt-out.

Linking to image from cutom component in VuePress

I want to display an image in my VuePress markdown file. Normally, I'd go with:
![My Image](./resources/myimg.png)
However, I'd like to create a custom Vue component that will style the images in a specific way. Then, some images would be displayed using the "standard" markdown syntax (like above), and some others using my custom component.
With my custom component, I'd display the images like this:
<MyComponent src="./resources/myimg.png"/>
As you can see, the images are placed alongside my markdowns, in a resources directory. This makes sense for me, because the image is close to the markdown where it gets displayed.
Unfortunately, the image does not get displayed when I use MyComponent. VuePress (webpack?) handles the images during build and places them in some other directory with a different name. The "standard" Markdown image reference works fine, its URL to the image is set up correctly by VuePress. However, MyComponent does not work, because the src parameter is just a string for VuePress and it does not transform it in any way.
I know that one solution would be to place my images in the /vuepress/public folder. However, I would want to keep the same organization as I have now - images alongside documents.
How can I achieve that?
I had the same issue.
I used the answer #papey provides for a Vue question here
Here is one thing he suggests
<template>
<div id="app">
<img :src="require('./assets/logo.png')"/>
</div>
</template>
<script>
export default {
}
</script>
<style lang="css">
</style>

How To Emit Only Gallery IMGs from Batflat CMS

If you make a Gallery in Batflat CMS, the template tag it creates will generate its only Bootstrap HTML for a gallery. What if I just want to emit IMG tags for the gallery items, instead?
Create a Gallerymod custom module. That way, your customization may likely survive a Batflat Update.
Copy inc/modules/galleries as inc/modules/gallerymod.
Remove the lang folder and Admin.php in your gallerymod folder.
Change the Name and Description inside the gallerymod/Info.php, as well as the comments. I used static strings instead of code. Also in this file, inside the install function and uninstall function, remove code inside those so that it does nothing on install or uninstall.
In your gallerymod/Site.php, look for the $assign[$gallery['slug']] assignment, and on the following line, add:
$assign[$gallery['slug'] . '-alt1'] = $this->draw('gallery-alt1.html', ['gallery' => $tempAssign]);
Also, where you have the namespace line set as namespace Inc\Modules\Galleries;, change it to namespace Inc\Modules\Gallerymod;.
In your gallerymod/view folder, create a gallery-alt1.html file and add these contents:
{loop: $gallery.items}
<img class="photo-{if: $value.title}{$value.title}{/if}" alt="" class="img-responsive" src="{?=url($value.src.lg)?}">
{/loop}
Now activate this inactive module in Batflat's admin system. You'll notice that it has no admin panel -- because it doesn't need one. You already have the Galleries one. Do not deactivate the Galleries module because the Gallerymod module relies on the Galleries module.
Now, from your custom theme template, you can call this by varying how you called the old slug. So, if your old way of calling the gallery was something like {$gallery.home-photos}, then you would merely tack on the "-alt1" on the end and call it like {$gallery.home-photos-alt1}. I like to wrap these in a DIV wrapper with an ID on it so that I can address it with CSS, jQuery, or Javascript.
In the Batflat Admin system, go back and edit your image titles in the gallery. Treat those titles like a slug (lowercase alphanumeric phrase with dashes) because these are used as class names on the IMG tags in gallery-alt1.html, and you may want to address these individually in CSS, jQuery, or Javascript, later on.
Refresh your browser and you may see the source code display something similar to:
<div id="hidden-images" class="hidden">
<img class="photo-man2" alt="" class="img-responsive" src="https://example.com/uploads/galleries/2/15831273220.jpg">
<img class="photo-woman1" alt="" class="img-responsive" src="https://example.com/uploads/galleries/2/15831272980.jpg">
<img class="photo-man1" alt="" class="img-responsive" src="https://example.com/uploads/galleries/2/15831272540.jpg">
</div><!-- hidden-images -->
Just remember that if you update your version of Batflat, that you may need to reapply this customization again -- it depends on what was done in the update to the existing Galleries module.
If you have different tastes as to how you want to format your images, just edit your gallery-alt1.html file. Plus, you can make multiples of these for different situations, such as gallery-alt2.html, gallery-alt3.html, etc. You can even make it emit JSON instead of html so that you can insert it into a Javascript block in your theme.
Another tip for debugging, in case your site won't load or the admin system breaks, is to edit inc/core/defines.php and change the DEV_MODE to false. That way, PHP will show you every error and that might help you in debugging what might be wrong.

Render an image conditionally in Vue with file loader

I'm using Webpack to compile my Vue production bundle and it loads my images properly because they are defined used <img> tags in my component. I want to load an additional image and show it based on a condition. Since the image isn't set initially in an <img> tag Webpack isn't loading it using file-loader. When I call:
event.currentTarget.children[2].innerHTML = "<img src='../assets/imgs/heart.png' />"
This doesn't work because heart.png was never processed by file-loader, while my previous images were. Any ideas on how to force Webpack to process this image without defining it in HTML my component. My other images (that work) look like this : <img src="data:image/png;base64,iVBORw0KGgo...=="> I understand why my image isn't loading (it's defined in a string), buy any suggestions?

Grails Resources plugin, modules and <r:img> to render images?

trying to learn the Resources plugin
From my understanding, it helps to define 'resources' such as css and javascript files and automatically pull them into your gsp's when needed. I understand how to create modules that can then be loaded in using tags etc.
The part im not understanding is this: http://grails-plugins.github.com/grails-resources/guide/4.%20Using%20resources.html#4.2%20Linking%20to%20images
So ive created a module called 'images' in Config.groovy as follows:
grails.resources.modules = {
images {
resource url:'/images/view.jpg', attrs:[width: 1280, height:720 , alt: 'my view']
resource url:'/images/breakfast.jpg', attrs:[width: 1280, height:720, alt: 'breakfast']
}
}
The resources are included in the .gsp page in the head section as follows:
<head>
<r:require modules="jquery-ui, blueprint"/>
</head>
i know the resources have been successfully added to the head section because when i inspect the page source i see them there:
<link href="/ResourceTest/static/Aa7jV0N2qZjOz7TLZ9cl5cREIh2y5jJYV0ytn4nQg9r.jpg" rel="shortcut icon" width="1280" height="720" alt="my view" />
<link href="/ResourceTest/static/IpQBSjrYeLDdSUBGbP3jhf6Kkhvu1zV3XRtwWfKOIMn.jpg" rel="shortcut icon" width="1280" height="720" alt="breakfast" />
My question is this: how are the image resources then used? i mean i know if it was javascript, the importing of the resource gives you access to use the functions in the html code, but with regards to images, the site says "Once you have done this, using to reference them would automatically set the width, height and other attributes."
How? I've tried the following:
<r:img module="images">
<r:img alt="breakfast">
and a handful of others with no success
what does work is:
<r:img uri="/images/breakfast.jpg">
but this works regardless of whether or not you add the module with the r:require tag.. So whats the point of using this plugin for images then and how would i use it?
The <r:img> tag works just fine with our without <r:require>; it even works with undeclared image resources.
The point of the require tag is to prevent resource duplication. So, for instance, suppose you have multiple javascript resources that rely on jQuery, and they're all required. Add another layer of complication: say you're actually pulling together different gsp templates via sitemesh, and they each have their own resource dependencies. If you just put the normal HTML code to reference those resources in the head of each gsp layout, you might get multiple instances of them in your page header, which could prove problematic. Using the resources plugin makes sure you only get one instance of the required resource.
See http://grails-plugins.github.io/grails-resources/ref/Tags/require.html and http://grails-plugins.github.io/grails-resources/ref/Tags/layoutResources.html.
With images, though, this is not really necessary. If you have an image more than once on a page, it's probably because you wanted it, or because you're applying redundant layouts and need to refactor a bit. So, you are correct that the require tag doesn't really do much for images called via <r:img>. This is simply because images are a different sort of resource, so they're treated differently. Don't sweat it. :)

Resources