Skip to content

Instantly share code, notes, and snippets.

@FlxSaenger
Created September 21, 2023 12:57
Show Gist options
  • Select an option

  • Save FlxSaenger/6237c6ee84bdde68623ca3f43281e897 to your computer and use it in GitHub Desktop.

Select an option

Save FlxSaenger/6237c6ee84bdde68623ca3f43281e897 to your computer and use it in GitHub Desktop.
qwik-image webp fallback component
import { component$, useComputed$, useContext } from '@builder.io/qwik';
import { type ImageProps, getSizes, getSrcSet, ImageContext } from 'qwik-image';
import { webpImageTransformer$ } from '~/routes/layout';
/**
* Custom image component that extends qwik-image in two ways:
*
* - Provides images both in webp and regular (fallback) format
* - Wraps <img> and <source> in <picture>
*
* Tested with qwik-image-0.0.8 (MIT license)
*/
export default component$((props: ImageProps) => {
const state = useContext(ImageContext);
const { resolutions, imageTransformer$, ...imageAttributes } = {
...state,
...props,
};
const imageAttributesWithoutChildren = {
...imageAttributes,
children: undefined,
};
const sizes = useComputed$(() => getSizes(props));
const srcSet = useComputed$(() => {
const { src, width, height, aspectRatio, layout } = props;
return getSrcSet({
src,
width,
height,
aspectRatio,
layout,
resolutions,
imageTransformer$,
});
});
const webpSrcSet = useComputed$(() => {
const { src, width, height, aspectRatio, layout } = props;
return getSrcSet({
src,
width,
height,
aspectRatio,
layout,
resolutions,
imageTransformer$: webpImageTransformer$,
});
});
const regularSrc = useComputed$(() => {
const { src, width, height } = props;
return imageTransformer$!({
src,
width,
height,
} as any);
});
imageAttributesWithoutChildren.src = regularSrc.value;
const width = useComputed$(() =>
['fullWidth', 'constrained'].includes(props.layout)
? undefined
: props.width
);
const height = useComputed$(() =>
['fullWidth', 'constrained'].includes(props.layout)
? undefined
: props.height
);
return (
<picture>
<source type="image/webp" srcSet={webpSrcSet.value} sizes={sizes.value} />
<img
decoding="async"
{...imageAttributesWithoutChildren}
src={regularSrc.value}
width={width.value}
height={height.value}
srcSet={srcSet.value}
sizes={sizes.value}
/>
</picture>
);
});
@FlxSaenger
Copy link
Author

Make sure to export both "imageTransformer$" and "webpImageTransformer$" in layout.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment