Skip to content

Commit adc9c45

Browse files
committed
feat(images): nuxt content transformer to add image metadata
1 parent a2f883c commit adc9c45

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

components/AttributeResponsiveImage.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
data-sizes="auto"
88
:alt="alt"
99
class="lazyload"
10+
:width
11+
:height
1012
>
1113
</template>
1214

@@ -16,6 +18,8 @@ interface Props {
1618
alt: string
1719
sizes?: string
1820
loading?: string
21+
width?: number
22+
height?: number
1923
aspectRatio?: string | boolean
2024
parentFit?: string | boolean
2125
}

nuxt.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ export default defineNuxtConfig({
1717
name: 'nuxt-attribute-content',
1818
},
1919
devtools: { enabled: true },
20+
content: {
21+
build: {
22+
transformers: [
23+
'#layers/nuxt-attribute-content/transformers/imageDimensions',
24+
],
25+
},
26+
},
2027
runtimeConfig: {
2128
public: {
2229
mapbox: {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"@nuxtjs/leaflet": "^1",
4848
"better-sqlite3": "^12.4.1",
4949
"happy-dom": "^18.0.1",
50+
"image-meta": "^0.2.2",
5051
"markdown-it": "^14.1.0",
5152
"nuxt-ipx-cache": "1.0.6",
5253
"nuxt-lazyimages": "^0.2.1",

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

transformers/imageDimensions.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { defineTransformer, type TransformedContent } from '@nuxt/content'
2+
import { resolvePath } from '@nuxt/kit'
3+
import { readFile } from 'node:fs/promises'
4+
import { imageMeta, type ImageMeta } from 'image-meta'
5+
6+
interface ImageItem {
7+
src: string
8+
metadata?: ImageMeta
9+
}
10+
11+
export default defineTransformer({
12+
name: 'imageDimensions',
13+
extensions: ['.yml'],
14+
transform: async function (content: TransformedContent) {
15+
await setImageDimensions(content)
16+
return content
17+
},
18+
})
19+
20+
const setImageDimensions = async (data: Record<string, unknown>) => {
21+
for (const property in data) {
22+
let item = data[property]
23+
if (item instanceof Object) {
24+
item = await setImageDimensions(item as Record<string, unknown>)
25+
}
26+
if (item && item instanceof Object && 'src' in item) {
27+
const imageItem = item as ImageItem
28+
try {
29+
const filePath = await resolvePath(`public${imageItem.src}`)
30+
const imageData = await readFile(filePath)
31+
imageItem.metadata = imageMeta(imageData)
32+
}
33+
catch {
34+
throw new Error(`Failed to parse image: ${imageItem.src}`)
35+
}
36+
}
37+
data[property] = item
38+
}
39+
return data
40+
}

0 commit comments

Comments
 (0)