npm package: @pixel-puppy/react
Description: Official React library for Pixel Puppy - Transform and optimize images with WebP conversion and smart resizing
Author: Christoffer Artmann
Latest version: 1.0.2

# @pixel-puppy/react

Official React library for [Pixel Puppy](https://pixelpuppy.io) - Transform and
optimize images with WebP conversion and smart resizing.

## Features

- **Simple React Component** - Drop-in replacement for `<img>` tags
- **Automatic WebP Conversion** - Serve modern image formats for better
  performance
- **Smart Responsive Images** - Automatic srcset generation with device
  breakpoints for optimal loading on all screen sizes
- **Multiple Strategies** - Intelligent selection between non-responsive, default,
  width-based, and sizes-based strategies
- **TypeScript Support** - Fully typed with comprehensive type definitions
- **Zero Configuration** - Works out of the box with sensible defaults
- **Ref Forwarding** - Access the underlying img element when needed

## Installation

### npm

```bash
npm install @pixel-puppy/react
```

### Bun

```bash
bun add @pixel-puppy/react
```

## Quick Start

```tsx
import { Image } from '@pixel-puppy/react'

function App() {
  return (
    <Image
      alt="A beautiful photo"
      project="my-project"
      src="https://example.com/photo.jpg"
    />
  )
}
```

## API Reference

### Image Component Props

#### Required Props

- `project` (string) - Your Pixel Puppy project identifier
- `src` (string) - The URL of the original image to transform

#### Transformation Options

- `width` (number, optional) - The desired width in pixels. The image will be
  resized to this width while maintaining aspect ratio. When provided without
  `sizes`, generates srcset with ALL common breakpoints plus width plus 2x
  variant.
- `format` ('webp' | 'png', optional) - The desired output format. Defaults to
  'webp' for optimal performance.
- `responsive` (boolean, optional) - Whether to generate responsive image
  attributes (srcset, sizes). When false, returns only a single src URL.
  Defaults to true.
- `sizes` (string, optional) - HTML sizes attribute value for responsive images.
  Describes the image's display size across different viewport widths. When
  provided, uses sizes-based srcset strategy with filtered breakpoints.
  Example: `"(min-width: 768px) 50vw, 100vw"`

#### Standard HTML Img Attributes

The Image component supports all standard HTML img element attributes including:

- `alt` - Alternative text for accessibility
- `className` - CSS classes
- `style` - Inline styles
- `loading` - Loading strategy ('lazy' | 'eager')
- `decoding` - Decoding hint ('async' | 'auto' | 'sync')
- `crossOrigin` - CORS settings
- And all other standard img attributes

### Ref Forwarding

The Image component forwards refs to the underlying img element:

```tsx
import { useRef } from 'react'
import { Image } from '@pixel-puppy/react'

function App() {
  const imgRef = useRef<HTMLImageElement>(null)

  return (
    <Image
      alt="A photo"
      project="my-project"
      ref={imgRef}
      src="https://example.com/photo.jpg"
    />
  )
}
```

### Responsive Image Strategies

The Image component automatically selects the best responsive image strategy
based on the props you provide:

1. **Non-responsive Strategy** (`responsive={false}`): Returns only a single src
   URL with no srcset or sizes. Use this when you want a specific image size
   without responsive behavior.

2. **Default Strategy** (no width or sizes): Generates srcset with all common
   device breakpoints (480w, 640w, 750w, 828w, 1080w, 1200w, 1920w, 2048w,
   3840w) and sets `sizes="100vw"`. Ideal for full-width images like heroes or
   banners.

3. **Width-based Strategy** (width provided, no sizes): Generates srcset with
   ALL common device breakpoints PLUS your provided width PLUS a 2x variant.
   Sets `sizes="(min-width: 1024px) 1024px, 100vw"`. Ensures mobile
   alternatives are always available while supporting high-DPI displays.

4. **Sizes-based Strategy** (sizes provided): Generates srcset filtered based on
   the smallest vw value in your sizes attribute. Automatically excludes
   unnecessary breakpoints for optimal performance.

## Usage Examples

### Non-responsive Mode (Single URL)

For when you need a specific size without responsive behavior:

```tsx
import { Image } from '@pixel-puppy/react'

function Avatar() {
  return (
    <Image
      alt="User avatar"
      project="my-project"
      responsive={false}
      src="https://example.com/avatar.jpg"
      width={64}
    />
  )
}
```

### Default Strategy (Full-Width Images)

Automatically generates srcset for all device breakpoints:

```tsx
import { Image } from '@pixel-puppy/react'

function Hero() {
  return (
    <Image
      alt="Hero image"
      className="w-full h-auto"
      project="my-project"
      src="https://example.com/hero.jpg"
    />
  )
}
// Generates srcset: 480w, 640w, 750w, 828w, 1080w, 1200w, 1920w, 2048w, 3840w
// Sets sizes="100vw"
```

### Width-based Strategy (Fixed Width with Mobile Alternatives)

Provides ALL breakpoints plus your width plus 2x for retina:

```tsx
import { Image } from '@pixel-puppy/react'

function ProductImage() {
  return (
    <Image
      alt="Product photo"
      project="my-project"
      src="https://example.com/product.jpg"
      width={800}
    />
  )
}
// Generates srcset: 480w, 640w, 750w, 800w, 1600w (2x), 1920w, 2048w, 3840w
// Sets sizes="(min-width: 1024px) 1024px, 100vw"
// Sets width={800}
```

### Sizes-based Strategy (Custom Responsive Behavior)

Filter breakpoints based on your layout needs:

```tsx
import { Image } from '@pixel-puppy/react'

function SidebarImage() {
  return (
    <Image
      alt="Sidebar image"
      project="my-project"
      sizes="(min-width: 1024px) 33vw, (min-width: 768px) 50vw, 100vw"
      src="https://example.com/sidebar.jpg"
      width={600}
    />
  )
}
// Automatically filters breakpoints based on smallest vw (33vw)
// Only includes breakpoints >= ~160px (33% of 480px)
```

### Custom Format

```tsx
import { Image } from '@pixel-puppy/react'

function Logo() {
  return (
    <Image
      alt="Company logo"
      format="png"
      project="my-project"
      src="https://example.com/logo.png"
      width={200}
    />
  )
}
```

### Lazy Loading

```tsx
import { Image } from '@pixel-puppy/react'

function ProductGrid() {
  return (
    <div className="grid grid-cols-3 gap-4">
      {products.map((product) => (
        <Image
          key={product.id}
          alt={product.name}
          className="rounded-lg"
          loading="lazy"
          project="my-project"
          src={product.imageUrl}
          width={400}
        />
      ))}
    </div>
  )
}
```

### Responsive Images for Different Screen Sizes

```tsx
import { Image } from '@pixel-puppy/react'

function ResponsiveImage() {
  return (
    <picture>
      <source
        media="(min-width: 1024px)"
        srcSet="https://pixelpuppy.io/api/image?project=my-project&url=https://example.com/photo.jpg&format=webp&width=1920"
      />
      <source
        media="(min-width: 768px)"
        srcSet="https://pixelpuppy.io/api/image?project=my-project&url=https://example.com/photo.jpg&format=webp&width=1024"
      />
      <Image
        alt="Responsive photo"
        project="my-project"
        src="https://example.com/photo.jpg"
        width={640}
      />
    </picture>
  )
}
```

### With Tailwind CSS

```tsx
import { Image } from '@pixel-puppy/react'

function Card() {
  return (
    <div className="max-w-sm rounded overflow-hidden shadow-lg">
      <Image
        alt="Card image"
        className="w-full"
        project="my-project"
        src="https://example.com/card-image.jpg"
        width={400}
      />
      <div className="px-6 py-4">
        <div className="font-bold text-xl mb-2">Card Title</div>
        <p className="text-gray-700 text-base">Card description</p>
      </div>
    </div>
  )
}
```

## TypeScript Support

This library is written in TypeScript and provides comprehensive type
definitions:

```tsx
import { Image, type ImageProps } from '@pixel-puppy/react'

const imageProps: ImageProps = {
  alt: 'A photo',
  format: 'webp',
  project: 'my-project',
  src: 'https://example.com/photo.jpg',
  width: 800
}

function MyImage() {
  return <Image {...imageProps} />
}
```

## How It Works

The Image component uses the
[@pixel-puppy/javascript](https://www.npmjs.com/package/@pixel-puppy/javascript)
library under the hood to build optimized image URLs. When you provide a
`project`, `src`, and optional transformation options, it constructs a Pixel
Puppy API URL that:

1. Fetches your original image
2. Converts it to the specified format (WebP by default)
3. Resizes it to the specified width (if provided)
4. Serves the optimized result through a global CDN

The component is a thin wrapper around the standard HTML `<img>` element,
forwarding all standard attributes and supporting ref forwarding.

## Related Packages

- [@pixel-puppy/javascript](https://www.npmjs.com/package/@pixel-puppy/javascript) -
  Core JavaScript/TypeScript library for building Pixel Puppy URLs

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for
details.

## License

MIT License - see [LICENSE](./LICENSE) for details.

## Support

- Documentation: https://pixelpuppy.io/docs
- Issues: https://github.com/Artmann/pixel-puppy-react/issues
- Email: support@pixelpuppy.io