React component for rendering HTML <source>
tag with nice abstractions over srcset and sizes attributes.
npm install @renditions/react-picture-source
Import react
and @renditions/react-picture-source
:
import React from 'react'
import Source from '@renditions/react-picture-source'
Define a renditions configuration:
const renditions = [
{ width: 320 },
{ width: 768 },
{ width: 1280 }
]
Define a getSrc
function that returns the source URL for a given rendition:
const getSrc = (filename, ext, rendition) => {
return `/images/${filename}_${rendition.width}.${ext}`
}
Define your PictureSource
component:
const PictureSource = ({ filename, ext, ...rest }) => (
<Source
renditions={renditions}
getSrc={getSrc.bind(null, filename, ext)}
{...rest}
>
)
Here's what this component renders to the DOM:
JSX:
<PictureSource filename="oranges" ext="webp" type="image/webp">
HTML:
<source
srcset="/images/oranges_320.webp 320w, /images/oranges_768.webp 768w, /images/oranges_1280.webp 1280w"
type="image/webp"
>
By default, the sizes
attribute is omitted. Not specifying this attribute can lead to the browser loading unnecessarily large images.
Read more about the sizes attribute here.
To render the sizes
attribute you can provide size
and breakpoints
props. Here's an example using the size
prop only:
JSX:
<PictureSource filename="oranges" ext="webp" size="50vw" type="image/webp">
HTML:
<source
srcset="/images/oranges_320.webp 320w, /images/oranges_768.webp 768w, /images/oranges_1280.webp 1280w"
sizes="50vw"
type="image/webp"
>
To specify different sizes for different viewport widths, you can provide a breakpoints
prop.
JSX:
<PictureSource
filename="oranges"
ext="webp"
size="100vw"
breakpoints={[
{
mediaMinWidth: '960px',
size: '100vw'
},
{
mediaMinWidth: '480px',
size: '50vw'
}
]}
type="image/webp"
>
HTML:
<source
srcset="/images/oranges_320.webp 320w, /images/oranges_768.webp 768w, /images/oranges_1280.webp 1280w"
sizes="(min-width: 960px) 100vw, (min-width: 480px) 50vw, 100vw"
type="image/webp"
>
The breakpoints
prop is expected to be an array sorted by mediaMinWidth
in descending order. Likewise, the renditions
prop is expected to be an array sorted by width
in ascending order.
To sort these automatically, you can set the autoSortBreakpoints
and autoSortRenditions
boolean props.