Skip to content

feat: adds datocms astro image - #355

Open
JopMolenaar wants to merge 16 commits into
mainfrom
feat/image-datocms-astro
Open

JopMolenaar wants to merge 16 commits into
mainfrom
feat/image-datocms-astro

Conversation

@JopMolenaar

@JopMolenaar JopMolenaar commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Changes

  • Adds datocms astro image for rendering responsive images

Associated issue

Resolves #356

How to test

  1. Open preview link
  2. Navigate to a page that uses an image
  3. Try resizing the screen and refresh to see the resized image
  4. Compare with what we had. New version uses DPR to scale images istead of setting scrSets in a function we made.
  5. Is it loading well?
  6. What if an image fails, does it show the correct fallback

Test broken image

  1. Go to image block demo
  2. Open dev tools -> Go to Network tab -> Select the Img filter
  3. Right mouse click on the image url -> hover over Block requests -> Click Block request URL.
  4. Refresh
  5. Image should not load. Background should be light gray with a message.
  6. Don't forget to unblock the URL afterwards ;)

Checklist

  • I have performed a self-review of my own code
  • I have made sure that my PR is easy to review (not too big, includes comments)
  • I have made updated relevant documentation files (in project README, docs/, etc)
  • I have added a decision log entry if the change affects the architecture or changes a significant technology
  • I have notified a reviewer

@JopMolenaar JopMolenaar self-assigned this Apr 24, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Apr 24, 2026

Copy link
Copy Markdown

Deploying head-start with  Cloudflare Pages  Cloudflare Pages

Latest commit: bb48fde
Status:🚫  Build failed.

View logs

@jbmoelker jbmoelker changed the title feat(): adds datocms astro image feat: adds datocms astro image Apr 30, 2026
@slimluccii
slimluccii force-pushed the feat/image-datocms-astro branch from 5fd9f58 to 44bb9f9 Compare May 19, 2026 09:41
@slimluccii
slimluccii marked this pull request as ready for review May 19, 2026 12:48
@slimluccii
slimluccii requested a review from jbmoelker May 19, 2026 12:54
import type { ImageBlockFragment } from '~/lib/datocms/types';
import { t } from '~/lib/i18n';

const defaultSizes = [1280, 960, 640, 320];

@slimluccii slimluccii May 19, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default way is with DPR now. Do we want to set our own DPR values? Or are the DatoCMS default sufficient?

srcSetCandidates = [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]

Copilot AI review requested due to automatic review settings May 19, 2026 13:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

Comment thread src/blocks/ImageBlock/Image.astro Outdated
};
type Props = HTMLAttributes<'figure'> & {
image: ImageBlockFragment['image']
priority?: boolean

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority is consistant with the DatoCMS Image component. Should we keep my change or revert it to loading?

url
responsiveImage {
aspectRatio
responsiveImage( imgixParams: { auto: [format, compress], q: 80, fit: max, w: 1200} ) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the 1200 width coming from? Max width of the default text block layout?

Either way I don't think we want to have imgix params here but instead closer to the component, probably passed down from the text block layout?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The q: 80, fit: max, w: 1200 is set here to have more control over the biggest image. Before this change we made our own srcSet steps, but now this is done with dpr. But wiuth only dpr we have no control over the largest possible img?

I think this place for the imgix params is the most logic place? The src set breakpoints also depend on this width. So if we set w after getting the srcSets, we get other breakpoints then that we serve?

srcSets when we append all imgix variables in the imgae.astro:

<source srcset="
https://www.datocms-assets.com/145765/1730394116-head-start-cover.jpg?dpr=0.25&amp;auto=format%2Ccompress&amp;q=80&amp;w=1200&amp;fit=max 482w,
https://www.datocms-assets.com/145765/1730394116-head-start-cover.jpg?dpr=0.5&amp;auto=format%2Ccompress&amp;q=80&amp;w=1200&amp;fit=max 965w,
https://www.datocms-assets.com/145765/1730394116-head-start-cover.jpg?dpr=0.75&amp;auto=format%2Ccompress&amp;q=80&amp;w=1200&amp;fit=max 1447w,
https://www.datocms-assets.com/145765/1730394116-head-start-cover.jpg?auto=format%2Ccompress&amp;q=80&amp;w=1200&amp;fit=max 1930w" 
sizes="(max-width: 1930px) 100vw, 1930px">

srcSets when we set max width in the query:

<source srcset="
https://www.datocms-assets.com/145765/1730394116-head-start-cover.jpg?dpr=0.25&amp;w=1200&amp;auto=format%2Ccompress&amp;q=80&amp;fit=max 300w,
https://www.datocms-assets.com/145765/1730394116-head-start-cover.jpg?dpr=0.5&amp;w=1200&amp;auto=format%2Ccompress&amp;q=80&amp;fit=max 600w,
https://www.datocms-assets.com/145765/1730394116-head-start-cover.jpg?dpr=0.75&amp;w=1200&amp;auto=format%2Ccompress&amp;q=80&amp;fit=max 900w,
https://www.datocms-assets.com/145765/1730394116-head-start-cover.jpg?w=1200&amp;auto=format%2Ccompress&amp;q=80&amp;fit=max 1200w,
https://www.datocms-assets.com/145765/1730394116-head-start-cover.jpg?dpr=1.5&amp;w=1200&amp;auto=format%2Ccompress&amp;q=80&amp;fit=max 1800w" 
sizes="(max-width: 1200px) 100vw, 1200px">

@JopMolenaar
JopMolenaar force-pushed the feat/image-datocms-astro branch from af4b8df to 95e7997 Compare June 3, 2026 09:08
JopMolenaar and others added 12 commits June 3, 2026 11:21
- Reuse HTMLAttributes<'figure'> for forwarded props; add typed
  imageProps escape hatch (omits data/imgClass/priority)
- Replace `loading` prop with `priority: boolean` to mirror the
  DatoCMS AstroImage API; vector path applies the same
  fetchpriority/loading pattern
- Add decoding="async" to vector img path
- Avoid mutating input prop: use const alt = image.alt ?? '' and
  forward alt into responsiveImage data
- Scope CSS under .image-block, merge duplicate selectors, use
  define:vars for the unavailable message

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The unavailable-message exposed via `define:vars` is consumed inside
a `content` declaration, which requires a quoted string. Without
quotes the declaration was invalid and the `::after` pseudo never
rendered. Use JSON.stringify to produce a valid CSS string literal
and handle any embedded quotes/backslashes safely.

Also collapse the duplicate `.image-block__image` selector into a
nested rule.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The vector `<img>` path has no inline sizing from DatoCMS, so the
`max-width: 100%` and `height: auto` rules are required to keep SVGs
from overflowing their container.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add tests for the unhappy flows around the ::after pseudo:
- the --unavailable-message CSS var must be a quoted CSS string
  literal, otherwise `content: var(...)` is invalid and the broken
  image styling never renders
- the alt attribute falls back to an empty string when the image
  alt is missing

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace physical properties with their logical equivalents so the
styling adapts to non-horizontal writing modes:

- max-width / width / height -> max-inline-size / inline-size / block-size
- top / left -> inset-block-start / inset-inline-start
- padding-top -> padding-block-start

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Inline the props literal (typing it as a variable triggered a
`Props & Props` intersection conflict against the renderer's
generic) and narrow the figure query to `HTMLElement` so `style`
is available.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`alt: null as unknown as string` lied about the type. The intent is
"CMS did not send an alt" - express that by omitting the prop and
annotating the missing required field with @ts-expect-error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@JopMolenaar
JopMolenaar force-pushed the feat/image-datocms-astro branch from 95e7997 to e9ff4dd Compare June 3, 2026 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use datocms astro image

5 participants