static/app/components/core/image/image.mdx
import {Container, Flex} from '@sentry/scraps/layout'; import {Text} from '@sentry/scraps/text';
import * as Storybook from 'sentry/stories';
import image from 'sentry-images/spot/habitsSuccessfulCustomer.jpg';
import {Image} from '@sentry/scraps/image';
export const documentation = import('!!type-loader!@sentry/scraps/image');
The Image component is a styled wrapper around the HTML `` element that provides sensible defaults for lazy loading and object-fit behavior. It extends all standard HTML image attributes while adding additional functionality for modern web applications.
An Image requires a src and alt prop for accessibility and functionality. Read here for more information on alt descriptions and how to write good alt descriptions for informative and complex images.
The Image component requires src and alt props for accessibility and functionality.
<Storybook.Demo> <Image src={image} alt="Sentry logo" /> </Storybook.Demo>
<Image src={image} alt="Sentry logo" />
For local images in the codebase, you must use the path loader by importing the image file. The sentry-images alias resolves to the static images directory and returns a URL that can be passed to the src prop.
import emptyState from 'sentry-images/spot/habitsSuccessfulCustomer.png';
<Image src={emptyState} alt="Empty state illustration" />;
This approach ensures that:
Important: Always use the webpack import pattern for local images. Do not use relative paths or string literals pointing to local files:
// ❌ WRONG: Don't use relative paths
<Image src="../../images/image.png" alt="Sentry logo" />
// ❌ WRONG: Don't use string paths to static files
<Image src="/static/images/image.png" alt="Sentry logo" />
// ✅ CORRECT: Import the image first
import image from 'sentry-images/image.png';
<Image src={image} alt="Sentry logo" />
The aspectRatio prop allows you to define the width-to-height ratio of the image container. This is useful for preventing layout shifts during image loading and creating consistent image dimensions across hero images and other layouts.
<Storybook.Demo> <Flex gap="lg"> <Container width="300px" border="primary"> <Image src={image} alt="16:9 aspect ratio" aspectRatio="16/9" /> </Container> <Container width="300px" border="primary"> <Image src={image} alt="4:3 aspect ratio" aspectRatio="4/3" /> </Container> <Container width="300px" border="primary"> <Image src={image} alt="1:1 aspect ratio" aspectRatio="1/1" /> </Container> </Flex> </Storybook.Demo>
<Image src={image} alt="16:9 aspect ratio" aspectRatio="16/9" />
<Image src={image} alt="4:3 aspect ratio" aspectRatio="4/3" />
<Image src={image} alt="1:1 aspect ratio" aspectRatio="1/1" />
The aspectRatio prop accepts any valid CSS aspect-ratio value, including:
"16/9", "4/3", "1/1""1.5" or "0.75""auto" keywordWhen combined with objectFit="cover", aspect ratio is particularly useful for creating consistent card layouts or hero images that maintain their proportions across different screen sizes.
The objectFit prop controls how the image content is sized within its container. It accepts 'contain' (default) or 'cover' values, which map to the CSS object-fit property.
The image is scaled to maintain its aspect ratio while fitting within the element's content box. The entire image is made visible.
<Storybook.Demo> <Container width="400px" height="200px" border="primary"> <Image src={image} alt="Sentry logo contained" objectFit="contain" width="100%" height="100%" /> </Container> </Storybook.Demo>
<Image
src={image}
alt="Sentry logo contained"
objectFit="contain"
width="100%"
height="100%"
/>
The image is sized to maintain its aspect ratio while filling the element's entire content box. The image may be clipped to fit.
<Storybook.Demo> <Container width="400px" height="200px" border="primary"> <Image src={image} alt="Sentry logo covered" objectFit="cover" width="100%" height="100%" /> </Container> </Storybook.Demo>
<Image
src={image}
alt="Sentry logo covered"
objectFit="cover"
width="100%"
height="100%"
/>
The loading prop controls when the browser should load the image. By default, images are lazy-loaded to improve initial page performance.
Images are loaded only when they're about to enter the viewport, reducing initial page load time and bandwidth usage.
import image from 'sentry-images/image.png';
<Image src={image} alt="Lazy loaded Sentry logo" loading="lazy" />;
Images are loaded immediately, regardless of their position in the viewport. Use this for above-the-fold images or critical content.
import image from 'sentry-images/image.png';
<Image src={image} alt="Eagerly loaded Sentry logo" loading="eager" />;
Use the onError callback to handle failed image loads by providing a fallback image. This is useful when displaying user-generated content or external images that might not be available.
import {useState} from 'react';
import image from 'sentry-images/image.png';
import fallbackImage from 'sentry-images/spot/habitsSuccessfulCustomer.png';
function ImageWithFallback() {
return (
<Image
src={image}
alt="User avatar"
onError={e => (e.currentTarget.src = fallbackImage)}
/>
);
}
In this example, if the primary image fails to load, the onError callback updates the src to use a local fallback image.
Use the srcSet and sizes attributes for responsive images that adapt to different screen sizes and pixel densities. Import each image size using the webpack path loader.
import logoSmall from 'sentry-images/logos/sentry-wordmark-dark-400x100.png';
import logoLarge from 'sentry-images/logos/sentry-wordmark-dark-800x200.png';
<Image
src={logoSmall}
srcSet={`${logoSmall} 1x, ${logoLarge} 2x`}
alt="Sentry wordmark logo"
sizes="(max-width: 600px) 100vw, 50vw"
/>;
Always provide meaningful alt text for images. The alt prop is required to ensure proper accessibility support for screen readers.
Read here about alt descriptions and how to write good alt descriptions for informative and complex images.
import image from 'sentry-images/image.png';
import emptyState from 'sentry-images/spot/habitsSuccessfulCustomer.jpg';
// Good: Descriptive alt text
<Image
src={emptyState}
alt="Illustration showing empty feedback inbox with mailbox"
/>
// Bad: Generic or missing alt text
<Image src={image} alt="image" />