DEV Community

Jaimin Patel
Jaimin Patel

Posted on AI-assisted

How I Made React Smart Image Easier to Use with Providers and Presets

Every project has that moment where image components start looking almost identical.

You keep adding the same props like responsive, placeholder="blur", retry, or transition over and over again. It works, but it also means updating image behavior later becomes repetitive.

While working on React Smart Image, I wanted a simpler way to keep image settings consistent across a project without creating wrapper components for every use case. That's why I added two features: SmartImageProvider and Image Presets.

The repetitive props problem

This is probably familiar.

<SmartImage
  src="/shoe-1.jpg"
  responsive
  placeholder="blur"
  retry={2}
  transition="fade"
/>

<SmartImage
  src="/shoe-2.jpg"
  responsive
  placeholder="blur"
  retry={2}
  transition="fade"
/>
Enter fullscreen mode Exit fullscreen mode

Nothing is wrong with this approach.

But when you have dozens of images, changing one shared setting means touching every component.

SmartImageProvider

SmartImageProvider lets you define default settings once and automatically apply them to every SmartImage inside your application.

Instead of repeating props everywhere, wrap your app once.

import { SmartImageProvider } from "@concatstring/react-smart-image";

function App() {
  return (
    <SmartImageProvider
      defaults={{
        responsive: true,
        retry: 2,
        placeholder: "blur",
        transition: "fade",
      }}
    >
      <AppRoutes />
    </SmartImageProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

Now your image component becomes much cleaner.

<SmartImage
  src="/shoe.jpg"
  alt="Running Shoe"
/>
Enter fullscreen mode Exit fullscreen mode

It still gets responsive loading, blur placeholders, retry handling, and transitions from the provider automatically.

Need different behavior for one image?

Component props still override the defaults.

<SmartImage
  src="/hero.jpg"
  priority
  transition="scale"
/>
Enter fullscreen mode Exit fullscreen mode

That flexibility makes it easy to keep global consistency while handling special cases.

Image Presets

After adding global defaults, I noticed another pattern.

Different types of images usually need different configurations.

Hero banners should load with priority.

Product images should support zoom.

User avatars should have fixed dimensions and skeleton loading.

Instead of remembering those combinations every time, I added Image Presets.

import { createImagePresets } from "@concatstring/react-smart-image";

const presets = createImagePresets({
  hero: {
    priority: true,
    responsive: true,
    transition: "fade",
  },

  product: {
    zoom: true,
    responsive: true,
    placeholder: "blur",
  },

  avatar: {
    width: 60,
    height: 60,
    skeleton: true,
  },
});
Enter fullscreen mode Exit fullscreen mode

Now using them is much simpler.

<SmartImage preset="hero" src="/hero.jpg" />

<SmartImage preset="product" src="/shoe.jpg" />

<SmartImage preset="avatar" src="/user.jpg" />
Enter fullscreen mode Exit fullscreen mode

One preset replaces several repeated props while keeping everything consistent.

Using both together

The best part is that these features work together.

<SmartImageProvider
  defaults={{ retry: 2 }}
  presets={presets}
>
  <App />
</SmartImageProvider>
Enter fullscreen mode Exit fullscreen mode

When a product image renders, it combines:

Provider defaults

Product preset settings

Component-specific props

The priority order is simple:

Component Props → Preset → Provider Defaults → Library Defaults.

Why I built it this way

My first thought was to create separate components like HeroImage, ProductImage, and AvatarImage.

But that quickly turns into more components to maintain.

Keeping everything inside a single SmartImage component felt much cleaner. Now, if I want every product image to retry failed requests or every hero image to use a different transition, I only need to update one place.

Final thoughts

These aren't massive features, but they've made day-to-day development much smoother for me.

Less repetitive code, more consistent image behavior, and fewer places to update when requirements change. If you're already using Smart Image, SmartImageProvider and Image Presets are worth trying together—they've become my default setup for handling images across a project.

Resources

Website: https://labs.concatstring.com/products/react-smart-image

GitHub Source Code: https://github.com/concatstring-account/react-smart-image

NPM: https://www.npmjs.com/package/@concatstring/react-smart-image

Live Demo: https://react-smart-image.netlify.app/

Top comments (0)