Skip to content

Astro Picture component generates duplicate images when used in multiple pages #8956

@bbbbaum

Description

@bbbbaum

Astro Info

Astro                    v3.4.0
Node                     v18.15.0
System                   macOS (arm64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             none

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

I have a structure as follows:

/
├── src/
│   └── assets/
│   └── content/
│       └── blogposts/
│       └── config.ts
│   └── pages/
│       └── blogposts/
│              └── [slug].astro
│       └── blogposts.astro
│       └── index.astro

The idea is to have:

  • a page with a list of all blogposts (blogposts.astro)
  • a page for each blogpost entry in collections ([slug].astro)

Every entry has an image property in its config.ts definition as follows:

import { z, defineCollection } from 'astro:content';

const blogpostsCollection = defineCollection({
	type: 'content',
	schema: ({ image }) => z.object({
		title: z.string(),
		author: z.string(),
		image: image(),
	})
});

export const collections = {
	'blogposts': blogpostsCollection
};

The issue occurs when I build this project, the image that is referenced in the content entry gets generated twice for every specified width.

In this particular case I have the same Picture component on two pages:

	<Picture
		src={entry.data.image}
		alt="Papaya"
		loading="eager" 
		sizes="(max-width: 448px) 400px, (max-width: 810px) 750px, 1050px"
		widths={[150, 450, 750, 1050, 1350]}
		formats={['avif', 'webp']}
		fallbackFormat="jpg"
	/>

Which should result in 19 images generated:

Instead, I get 37 images - everything except that 1 randomly generated image is duplicated.

This doesn't really sound like an intended behaviour, and it might have something to do with the way I'm using collection entry objects but I'm all out of ideas how to circumvent it within my project.

In [slug].astro page:

// ...
export async function getStaticPaths() {
  const entries = await getCollection('blogposts');
  return entries.map(entry => ({
    params: { slug: entry.slug }, props: { entry },
  }));
}
const { entry } = Astro.props;
const { Content } = await entry.render();

// ...
<Picture
  src={entry.data.image}
  alt="Papaya"
  loading="eager" 
  sizes="(max-width: 448px) 400px, (max-width: 810px) 750px, 1050px"
  widths={[150, 450, 750, 1050, 1350]}
  formats={['avif', 'webp']}
  fallbackFormat="jpg"
/>
// ...

In blogposts.astro page:

// ...
const allBlogposts = await getCollection('blogposts');

// ...
allBlogposts.map((blogpost, index) => (
	<Picture
		src={blogpost.data.image}
		alt="Papaya"
		loading="eager" 
		sizes="(max-width: 448px) 400px, (max-width: 810px) 750px, 1050px"
		widths={[150, 450, 750, 1050, 1350]}
		formats={['avif', 'webp']}
		fallbackFormat="jpg"
	/>
))
// ...

I think I've mentioned everything that is of importance, but I have also created a repository with the example code so you can try it yourself and see what happens.

What's the expected result?

I expected no duplication of images since they belong to the same collection entry. I have a book review website with plenty of images and with this behaviour i get a major bump of images that are being generated (from 2k to 4k).

Link to Minimal Reproducible Example

https://github.com/bbbbaum/astro-picture-duplicates-investigation

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P3: minor bugAn edge case that only affects very specific usage (priority)feat: assetsRelated to the Assets feature (scope)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions