nuxt / image Goto Github PK
View Code? Open in Web Editor NEWPlug-and-play image optimization for Nuxt applications.
Home Page: https://image.nuxt.com
License: MIT License
Plug-and-play image optimization for Nuxt applications.
Home Page: https://image.nuxt.com
License: MIT License
I think for longer term it would be better to create observer directly in component instead of share runtime logic (createObserver(image))
propoed in #66 (comment) by @pi0
<nuxt-image fit="contain"....
It seems the fit property is always set to 'cover' no matter what it is defined
If I loop through an array with v-for the images are not found with a 404 error
<div v-for="image in product[0].images" v-bind:key="image.rank">
<nuxt-image :src="require(
~/assets/images/shop/${image.image_570xN})" />
</div>
but if I just use the img tag, the image is found
<div v-for="image in product[0].images" v-bind:key="image.rank">
<img :src="require(
~/assets/images/shop/${image.image_570xN})" />
</div>
Please can someone suggest a solution?
When setting a fixed width on the following line, it prevents classes to change the width and therefore makes it unable to make dynamic cover width.
image/src/runtime/nuxt-image.ts
Line 70 in 3ac6040
Example there should be possible, but isn't because the width is overrided by the component.
<div>
<nuxt-image
src="https://images.unsplash.com/photo-1602536052359-ef94c21c5948"
height="1000px"
width="1000px"
class="w-32 h-64" />
</div>
<NuxtImage :responsive="true">
~> <NuxtImage layout="responsive">
I'm using https://github.com/juliomrqz/nuxt-optimized-images to optimize webp and lqip for placeholder image. Can I use this nuxt/image to load image from there. eg: <nuxt-image :src="require('@/assets/images/banner/slider-sport.jpg?webp')"/>
I am using module with Cloudinary, and have setup like:
image: {
presets: [
{
name: '4/3',
modifiers: {
fit: 'cover',
format: 'auto',
}
}
],
providers: {
cloudinary: {
baseURL: 'https://res.cloudinary.com/nuxt/image/upload/'
}
}
},
<NuxtImage sizes="100,300:300,500:500,1000:1000" responsive src="cloudinary+4/3:/vue-telemetry/4d02deda597adab13fac9341c22458aa.jpg" />
I expect module to generate srcset with different size image variations, but got same image url for each viewport:
<img alt="4d02deda597adab13fac9341c22458aa" class="__nim_o" style="position: absolute; left: 0px; top: 0px; margin: 0px; width: 100%; height: 100%; object-fit: cover; object-position: center center; transition: opacity 800ms ease 0ms; opacity: 1;" src="https://res.cloudinary.com/nuxt/image/upload/c_fit,f_auto/vue-telemetry/4d02deda597adab13fac9341c22458aa.jpg" srcset="https://res.cloudinary.com/nuxt/image/upload/c_fit,f_auto/vue-telemetry/4d02deda597adab13fac9341c22458aa.jpg 100w, https://res.cloudinary.com/nuxt/image/upload/c_fit,f_auto/vue-telemetry/4d02deda597adab13fac9341c22458aa.jpg 300w, https://res.cloudinary.com/nuxt/image/upload/c_fit,f_auto/vue-telemetry/4d02deda597adab13fac9341c22458aa.jpg 500w, https://res.cloudinary.com/nuxt/image/upload/c_fit,f_auto/vue-telemetry/4d02deda597adab13fac9341c22458aa.jpg 1000w" sizes="(min-width: 1000px) 1000px, (min-width: 500px) 500px, (min-width: 300px) 300px, 100px">
Reproduction: https://github.com/bdrtsky/image-module-issues
I believe using ipx or other module to get the image ratio would be a huge improvement for DX so we could guess the height (if only width given) or width (if only height given)
By default the image transitions the blur when the image is fully loaded. There should be an option to opt in/out of this behaviour. The transition will cause lag in some cases because blur transitions are resource hungry.
I saw that internally you used the IntersectionObserver API by default instead of the new loading attribute.
I know that the loading attribute is not well supported yet... but there's a lightweight polyfill that you could use today.
It is only 2.88 KB for the minified version. Moreover, the polyfill is compatible down to IE 9.
In order to make a huge improvement for todays web performance challenges, you could implement the loading attribute polyfill.
This means less code maintenance, consequently less potential technical debt and a faster seo friendly nuxt-image component.
It could also allow you to avoid development errors (and therefore new issues from the community) due to custom providers urls encoding, url transformations and static generation.
hey all, first-time user here, vanilla reproduction steps:
yarn add @nuxt/image
modules: [ ... '@nuxt/image', ... ]
<nuxt-image src="placekitten.com/200/300" />
page returns Cannot read property 'validate' of undefined
:
this happens with any source:
src="~/assets/img/seats.jpg"
src="http://placekitten.com/200/300"
<nuxt-image />
the site is universal with static target (SSG)
export default {
// Target (https://go.nuxtjs.dev/config-target)
target: 'static',
// Global page headers (https://go.nuxtjs.dev/config-head)
head: {
title: 'portfolio',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{
hid: 'description',
name: 'description',
content: 'the beautiful works of lewis lloyd (@lloydtao)',
},
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
},
// Global CSS (https://go.nuxtjs.dev/config-css)
css: [],
// Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
plugins: [],
// Auto import components (https://go.nuxtjs.dev/config-components)
components: true,
// Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)
buildModules: [
// https://go.nuxtjs.dev/eslint
'@nuxtjs/eslint-module',
// https://go.nuxtjs.dev/tailwindcss
'@nuxtjs/tailwindcss',
],
// Modules (https://go.nuxtjs.dev/config-modules)
modules: [
// https://go.nuxtjs.dev/axios
'@nuxtjs/axios',
// https://go.nuxtjs.dev/pwa
'@nuxtjs/pwa',
// https://go.nuxtjs.dev/content
'@nuxt/content',
// https://image.nuxtjs.org/usage
'@nuxt/image',
],
// Axios module configuration (https://go.nuxtjs.dev/config-axios)
axios: {},
// Content module configuration (https://go.nuxtjs.dev/config-content)
content: {},
// PWA module configuration (https://pwa.nuxtjs.org/setup)
pwa: {
meta: {
theme_color: '#111119',
},
},
// Build Configuration (https://go.nuxtjs.dev/config-build)
build: {},
}
{
"name": "portfolio",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"lint:js": "eslint --ext .js,.vue --ignore-path .gitignore .",
"lint": "yarn lint:js",
"test": "jest"
},
"dependencies": {
"@nuxt/content": "^1.9.0",
"@nuxt/image": "0.0.4",
"@nuxtjs/axios": "^5.12.2",
"@nuxtjs/pwa": "^3.0.2",
"core-js": "^3.6.5",
"nuxt": "^2.14.6"
},
"devDependencies": {
"@nuxtjs/eslint-config": "^3.1.0",
"@nuxtjs/eslint-module": "^2.0.0",
"@nuxtjs/tailwindcss": "^3.1.0",
"@vue/test-utils": "^1.1.0",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.5.0",
"eslint": "^7.10.0",
"eslint-config-prettier": "^6.12.0",
"eslint-plugin-nuxt": "^1.0.0",
"eslint-plugin-prettier": "^3.1.4",
"jest": "^26.5.0",
"prettier": "^2.1.2",
"vue-jest": "^3.0.4"
}
}
Next.js forces an image to be a certain aspect ratio using inline styles, eg:
<div style="position: relative; padding-top: (aspect ratio); ...">
<img style="position: absolute; ..." src="..." />
</div>
Now the outer container doesn't rely on a fixed width. A fixed width will break layouts in many cases
The cover image in the Introduction section of the website https://image.nuxtjs.org/ is broken.
export default {
image: {
cloudinary: {}
}
random: {
provider: '~~/providers/random',
options: {
}
}
}
As per docs,
When you define an image with src props, Nuxt automatically calculates aspect ratio of the image and set size of the image based on the aspect ratio. The image's width will be equal to width of parent element in DOM and its height calculates based on the aspect ratio.
However unless width and height are defined, just setting
<template>
<nuxt-image src="/nuxt-icon.png" />
</template>
image rendered size is 0x0
Hello, I just installed nuxt image but when I try to load image from static folder I get an error:
GET http://localhost:3000/_image/ipx/local/_/_/the_eye_slow.gif 400 (Bad Request)
My component:
<template>
<div @click="countClick()">
<UiSpacer top />
<nuxt-image
:src="`/the_eye_${state}.gif`"
alt="oeil du jeu"
:width="imgDimention"
:height="imgDimention"
/>
</div>
</template>
<script>
import getTailwindBps from '@/mixins/getTailwindBps.js'
export default {
name: 'UiEye',
components: {
UiSpacer: require('@/components/ui/UiSpacer.vue').default,
},
mixins: [getTailwindBps],
props: {
state: {
type: String,
required: true,
validator(value) {
return ['focus', 'normal', 'slow']
},
},
},
My image is stored in the root of static folder. Can someone help me ?
- width: number | undefined
- height: number | undefined
- fit: cover | contain | fill | inside | outside
- format: string
local
to ipx
local
option to configure local providerAgain, I haven't actually played with this yet. But what would be cool is the ability to mark an image as a lazy preload (similar to lazysizes).
What it does is, when there is no scrolling, activity etc.. any image marked as preload would be lazy loaded even when it's not within the viewport. We do this for our menu items. They aren't viewable when you first hit the site, but we want the images ready when people use our menu, but only after the rest of the critical assets are loaded.
example https://realtruck.com/
cc: @pi0
or alias..
[ipx feature]
I haven't played with this yet, but per our Nuxt Meeting today, @pi0 wanted me to put this in as a reminder.
We should be able to eager load images just BELOW the viewport (similar to lazysizes). The goal is for the user to never actually have to see an image load. I assume this window (#px) would be configurable in the nuxt config and maybe even at other levels.
You should be able to just pass a rootMargin to the observer options with the required eager amount.
You could also take into account the device/network to expand the eager window (similar to what Chrome does for loading=lazy)
Whenever I set the dir option for the local provider, it give me a 404 in the console and image is not showing up.
I would be able to use images from assets folder at the end.
I used the very last version, fixing the sizing behavior.
It is working properly if I don't set the dir option.
Great module otherwise, finally something that can compare to gridsome g-image 👍
Hey guys,
Do you have more examples or could you elaborate more on how the srcset sizes get generated. I've spent hours trying to figure it out when using the sizes
prop.
Thanks in advance!
I am using Vuetify Image component and nuxt-optimized-images module. I am considering changing from using local image assets to using cloudinary but unfortunately nuxt-optimized-images does not support this. I have a hero image component that I am considering changing to use cloudinary and this module looks promising. Is there a way to use vuetify v-img
component with this module? Would it be possible to add a slot to the nuxt-image
component and use slot props on the v-img
?
Here is how I am using nuxt-optimized-images
and vuetify
in my hero image component.
<template>
<v-container class="pa-0 hidden-print-only" style="max-width: 1785px">
<v-row no-gutters align="center" justify="center">
<v-col cols="12" align-self="center">
<v-card :color="color || backgroundColor(src)[0]" flat dark tile>
<v-img
:lazy-src="_src(src).placeholder"
:src="_src(src).src"
:srcset="_src(src).srcSet"
:height="height"
width="1785"
sizes="(max-width: 1785px) 100vw, 1785px"
:gradient="gradient"
>
<slot>
<v-container
class="fill-height align-items-end justify-start"
fluid
>
<v-row align="center" justify="center">
<v-col class="text-center" cols="12">
<h1 v-if="heading" class="mb-4 text-shadow">
{{ heading }}
</h1>
<h2 v-if="subheading" class="subheading text-shadow">
{{ subheading }}
</h2>
</v-col>
</v-row>
</v-container>
</slot>
</v-img>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
props: {
heading: { type: String, default: null },
subheading: { type: String, default: null },
gradient: {
type: String,
default: 'rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)',
},
height: { type: [Number, String], default: 500 },
color: {
type: String,
default: null,
},
src: {
type: String,
default: './header-bg.jpg',
},
},
methods: {
backgroundColor: require.context(
'~/assets/img?lqip-colors',
true,
/\.(png|jpe?g).*$/,
),
_src: require.context(
`~/assets/img?resize&sizes[]=320&sizes[]=600&sizes[]=900&sizes[]=1785&sizes[]=4686&placeholder&format=webp`,
true,
/\.(png|jpe?g).*$/,
),
cover: require.context(
`~/assets/img?resize&size=1200&format=jpg`,
true,
/\.(png|jpe?g).*$/,
),
},
head() {
return {
meta: [
{
hid: 'og:image',
property: 'og:image',
content: `${this.$config.BASE_URL}${this.cover(`${this.src}`).src}`,
},
{
hid: 'og:image:width',
property: 'og:image:width',
content: this.cover(`${this.src}`).width,
},
{
hid: 'og:image:height',
property: 'og:image:height',
content: this.cover(`${this.src}`).height,
},
],
};
},
};
</script>
When the generated url is not valid for any reason (wrong modifier passed, wrong format, etc), it throws the error on the call data.buffer()
- Attempt to write outside buffer bounds
. The error is not clear what went wrong.
Expected: A more readable message to inform user about the invalid url.
to override options.provider` (we may also auto detect it based on deployment target)
The EXIF info of an image contains a 'rotation flag'. When resizing the image, it should take this into account. Almost all the apps only manipulate this flag
when asking to rotate.
This was my ugly hacked code for Hugo (Go). But I'm much better at Vue and converting my Hugo project to Nuxt static. I'm willing to add this to your package as a pull -- but I do not know where to start. Deadline. Very Tired.
{{ $orientation := 1 }}
{{ with $image.Exif }}
{{ $orientation = .Tags.Orientation }}
{{ end }}
{{ if eq $orientation 1 }}
{{ $image := .Resize "480x" }}
{{ else if (eq $orientation 8) }}
// Rotate the image 90deg CCW (.Resize "r90")
{{ $image := .Resize "480x" "r90" }}
{{ end }}
obligatoire stackoverflow thing:
https://stackoverflow.com/questions/13872331/rotating-an-image-with-orientation-specified-in-exif-using-python-without-pil-in
resources:
From what I read in the doc and what I experiment, the width
and height
attributes are mandatory. This is a good thing for the CLS reasons explained in the doc but I think they are currently misused. The main reason we have to put width
and height
on img
elements is to inform the browsers about the aspect ratio.
Here is a quote of Addy Osmani on the subject (full article here).
Modern browsers now set the default aspect ratio of images based on an image's width and height attributes so it's valuable to set them to prevent layout shifts. Thanks to the CSS Working Group, developers just need to set width and height as normal and the UA stylesheets of all browsers add a default aspect ratio based on the element's existing width and height attributes.
In the current implementation, the width
is used to define the width of the container which in responsive development is a blocking behavior. I think developers should be responsible for sizing their items while nuxt-image
should adopt a responsive approach with relative sizings.
Eg: https://codepen.io/twicpics/pen/627fd52cd4dc523ff72c2fadef9b78a0?editors=1100
Then let browsers choose the correct image by playing with srcset
.
Eg: https://codepen.io/twicpics/pen/b87821d341540afe22cd079059536f84?editors=1100
Regarding the placeholder behavior, same idea: the padding-top
trick could be dynamically computed by using CSS calc()
.
.placeholder {
padding-top: calc(height / width * 100%);
}
Eg: https://codepen.io/twicpics/pen/d6317ba5001ecdd3f2920d7dfb2e782a?editors=1100
I didn't dig into the "fit" attribute but it shouldn't be a problem.
Does it make sens?
I think this makes more sense, this is the name used is providers as well as Gridsome <g-image>
After reading nuxt/image's core code (and especially the loadProvider function), the only way I found to pass options to a custom provider is by setting its name as the provider's path.
By using this method we won't be able to use the provider's name when setting the nuxt-image component's src attribute.
I could be nice to have an easier way to give arguments to the provider, instead of hardcoding things within it.
When I changed tags from <img to <nuxt-image, image file disappeared from the page, when I inspected I realized it had position: absolute;
which was the reason why images get hidden. It's related to how TailwindCSS works.
here's my component itself:
<div class="relative flex flex-row items-center justify-center w-3/6 mb-5">
<div class="absolute top-0 left-0 w-48 h-10 pr-10 -ml-48 " >
{{ imageCaption }}
<div>
<div class="mt-2" >
<slot></slot>
</div>
</div>
</div>
<nuxt-image :src="imageSource" width="300" height="169" />
</div>
Tried to overwrite the <nuxt-image css but it affected the div not the image img itself.
Thanks.
Once I try to use the example I get an error:
provider.provider.generateURL is not a function
repro link: https://codesandbox.io/s/nuxt-image-tlgwe?file=/providers/wonder/index.js
I also don't see the actual preview in the docs which I guess means that example is broken there too: https://take.ms/CWCGb
If you use NuxtImage
without width
& height
, like
<NuxtImage src="cloudinary:/vue-telemetry/4d02deda597adab13fac9341c22458aa.jpg" />
it will inject placeholder base64 data into payload.
If you add width
& height
like
<NuxtImage width="4" height="3" src="cloudinary:/vue-telemetry/4d02deda597adab13fac9341c22458aa.jpg" />
placeholder disappears from payload.
Reproduction: https://github.com/bdrtsky/image-module-issues
The nuxt-image
component stops working when using a non-default base path, i.e. something like /my-base-path
instead of /
.
If this is a configuration issue, would it please be possible to describe in the docs how to modify the nuxt image config to work with non-default base paths?
Thanks.
I'm trying to use @nuxt/image with local files inside /static dir, first tried to use local setup
image: {
providers: {
local: {
dir: '~/static',
clearCache: false,
},
},
},
then this error showed up, didn't find examples in docs, but using a quick GitHub search I found that in some nuxt docs websites there wasn't image: {}
in some cases, same error didn't change when I removed the local configuration.
Thes are my packages :
"dependencies": {
"@bazzite/nuxt-optimized-images": "^0.4.0",
"@nuxt/content": "^1.10.0",
"@nuxtjs/pwa": "^3.2.2",
"@tailwindcss/typography": "^0.2.0",
"core-js": "^3.6.5",
"nuxt": "^2.14.7",
"nuxt-i18n": "^6.15.4",
"nuxt-lazyimage": "^2.0.1",
"plyr": "^3.6.2",
"vue-observe-visibility": "^0.4.6",
"vue-plyr": "^6.0.4",
"vue-scrollactive": "^0.9.3",
"vue-tippy": "^4.7.2"
},
"devDependencies": {
"@nuxt/image": "^0.0.3",
"@nuxtjs/html-validator": "^0.1.1",
"@nuxtjs/tailwindcss": "^3.2.0",
"add": "^2.0.6",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-prettier": "^3.1.4",
"imagemin-mozjpeg": "^9.0.0",
"lqip-loader": "^2.2.1",
"prettier": "^2.1.2",
"responsive-loader": "^2.2.0",
"webp-loader": "^0.6.0",
"yarn": "^1.22.10"
}
Thanks.
Build failed on netlify using spa mode
5:43:50 PM: $ nuxt build --spa
5:43:51 PM: [warn] `mode` option is deprecated. Please use `ssr: true` for universal mode or `ssr: false` for spa mode and remove `mode` from `nuxt.config`
5:44:25 PM: [fatal] Cannot destructure property `port` of 'undefined' or 'null'.
5:44:25 PM: at node_modules/@nuxt/image/dist/index.js:113:15
5:44:25 PM: at node_modules/hable/dist/hable.js:1:1052
5:44:25 PM: at node_modules/hable/dist/hable.js:1:270
5:44:25 PM: at async Nuxt.callHook (node_modules/hable/dist/hable.js:1:1021)
5:44:25 PM: at async Generator.generate (node_modules/@nuxt/generator/dist/generator.js:132:5)
5:44:25 PM: at async Object.run (node_modules/@nuxt/cli/dist/cli-build.js:105:7)
5:44:25 PM: at async NuxtCommand.run (node_modules/@nuxt/cli/dist/cli-index.js:2809:7)
Hi there !
For now, providers only generate URLs but it may prove problematic for some providers and transformations. For instance, TwicPics does not (and probably never will) pad images when doing a contain
transformation. It could be nice if a provider was able to specify the object-fit
that should be applied to the underlying img
element. Letting a provider return an Object
with a url
and fit
property as an alternative to a bare string
would suffice. If a provider returns a bare string
just use the default object-fit
.
Another area that could be buffed up too is regarding placeholders. At TwicPics, we're currently working on implementing different kinds of placeholders. It would be nice if a provider could expose a method that would be separate from generateURL
(say generatePlaceholderURL
). If a Provider does not provide a generatePlaceholderURL
method, just call generateURL
using the default transformation currently computed by nuxt-image.
Finally, but it may be out of scope for nuxt-image, we have a script at TwicPics that takes care of API calls generation based on the context of the page (users put the URL of the master image in data-src
and size their image using CSS, we generate the src
attribute on the fly and dynamically, plus we handle lazy loading to boot). To support such a feature would require a lot more control over the generated HTML but, as I said, it may be out of scope here.
Please let me know if this all makes sense.
q_auto
parameter was advised by one of the Cloudinary employees, for easier and more optimised quality setting for images.
I tried to use it, but it seems like there's no option to do that.
The end url should look like https://res.cloudinary.com/nuxt/image/upload/w_1200,h_900,f_auto,q_auto/vue-telemetry/4d02deda597adab13fac9341c22458aa.jpg
Nuxt config:
export default {
target: 'static',a
buildModules: ['@nuxtjs/tailwindcss'],
modules: ['@nuxt/image',],
image: {
providers: {
cloudinary: {
baseURL: 'https://res.cloudinary.com/milos5593/image/upload/',
},
},
},
}
And then in the component:
<template>
<header class="bg-black">
<div class="p-4 max-w-screen-xl">
<!-- Logo -->
<nuxt-link
class="font-bold text-lg text-white focus:outline-none focus:shadow-outline"
to="/"
>
<nuxt-image
class="w-56 h-auto"
fit="contain"
:placeholder="true"
:src="'cloudinary:/crossroads_logo.png'"
no-script
/>
</nuxt-link>
</div>
</header>
</template>
<script>
export default {
name: 'SiteHeader',
}
</script>
I'd suggest image src
should be set to a transparent base64 pixel when not loaded - e.g.
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
Otherwise the HTML won't validate, and there are potential other issues.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.