Snapkit Next.js Demo

Explore the features of Snapkit's Next.js image components rendering and optimizations.

Basic Image Usage

Live Demo

Basic Image

Fox image
import { Image } from '@snapkit-studio/nextjs';

function BasicExample() {
  return (
    <Image
      src="/landing-page/fox.jpg"
      alt="Fox image"
      width={400}
      height={300}
      className="rounded-lg border"
    />
  );
}

Fill Mode (Fill the container)

Fox image - Fill mode
// Image that fills the container
<div className="relative w-full h-64">
  <Image
    src="/landing-page/fox.jpg"
    alt="Fox image - Fill mode"
    fill
    className="object-cover"
  />
</div>

Different Sizes

Small imageMedium imageLarge image
// Images in different sizes
<div className="flex gap-4">
  <Image src="/landing-page/fox.jpg" alt="Small image" width={120} height={90} />
  <Image src="/landing-page/fox.jpg" alt="Medium image" width={200} height={150} />
  <Image src="/landing-page/fox.jpg" alt="Large image" width={300} height={225} />
</div>

Shows the fundamental usage of the Snapkit Image component.

CDN Configuration

Live Demo

Current CDN Configuration

Provider:snapkit
Base URL:https://snapkit-cdn.snapkit.studio

Standard Quality (85%)

CDN Example - Standard

High Quality (95%)

CDN Example - High Quality
🚀 Snapkit Provider (provider: "snapkit")
  • • Fully managed CDN service
  • • Automatic optimization
  • • Smart format delivery
  • • Global edge caching
  • • Zero configuration needed
🔧 Custom Provider (provider: "custom")
  • • Bring your own CDN
  • • Works with any CDN service:
  • - AWS CloudFront
  • - Google Cloud CDN
  • - Cloudflare
  • - Your own infrastructure
  • • Full control over configuration

This example demonstrates how the CDN provider configuration works. There are two provider types: 'snapkit' (managed service) and 'custom' (bring your own CDN). With the 'custom' provider, you can use any CDN service like CloudFront, Google Cloud, Cloudflare, or your own infrastructure.

Implementation

import { Image } from '@snapkit-studio/nextjs';
import { getCdnConfig } from '@snapkit-studio/core';

// Option 1: Snapkit managed CDN
// NEXT_PUBLIC_IMAGE_CDN_PROVIDER=snapkit
// NEXT_PUBLIC_SNAPKIT_ORGANIZATION=your-org

// Option 2: Custom CDN (any provider)
// NEXT_PUBLIC_IMAGE_CDN_PROVIDER=custom
// NEXT_PUBLIC_IMAGE_CDN_URL=https://your-cdn.example.com
// Examples: CloudFront, Google Cloud CDN, Cloudflare, etc.

function CdnExample() {
  return (
    <Image
      src="/images/sample-1.jpg"
      alt="CDN Example"
      width={400}
      height={300}
      quality={90}
    />
  );
}

Image Transform Effects

Live Demo

Basic Transform Effects

Original

Original image

Grayscale

Grayscale image

Blur Effect

Blurred image

Horizontal Flip (Flop)

Horizontally flipped image
// Basic transform effects
<Image
  src="/landing-page/fox.jpg"
  alt="Grayscale image"
  width={200}
  height={150}
  transforms={{ grayscale: true }}
/>

<Image
  src="/landing-page/fox.jpg"
  alt="Blurred image"
  transforms={{ blur: 5 }}
/>

<Image
  src="/landing-page/fox.jpg"
  alt="Horizontal flip"
  transforms={{ flop: true }}
/>

Flip Effects

Original

Original

Vertical Flip (Flip)

Vertically flipped

Horizontal + Vertical Flip

Both flips
// Flip effects
<Image transforms={{ flip: true }} />      // Vertical flip
<Image transforms={{ flop: true }} />      // Horizontal flip
<Image transforms={{ flip: true, flop: true }} />  // Both

Composite Transform Effects

Grayscale + Blur

Grayscale + blur

Horizontal + Vertical Flip + Grayscale

Composite effect

Full Effect Combo

Full effect
// Composite transform effects
<Image
  src="/landing-page/fox.jpg"
  transforms={{
    grayscale: true,
    blur: 3
  }}
/>

<Image
  transforms={{
    flip: true,
    flop: true,
    grayscale: true
  }}
/>

<Image
  quality={70}
  transforms={{
    grayscale: true,
    blur: 2,
    flop: true,
  }}
/>

Demonstrates how to apply a variety of image transforms.

Responsive Images

Live Demo

Basic Responsive Image

Let the browser pick the optimal image size automatically.

Responsive image
<Image
  src="/landing-page/fox.jpg"
  alt="Responsive image"
  width={800}
  height={600}
  className="w-full max-w-2xl"
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>

Different sizes Configurations

Mobile: 100%, Tablet: 50%, Desktop: 33%
Mobile-first responsive
Mobile: 320px, Tablet: 50%, Desktop: 400px
Fixed + percentage mix
// Example sizes configurations
<Image
  sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
/>

<Image
  sizes="(max-width: 640px) 320px, (max-width: 1024px) 50vw, 400px"
/>

Responsive Grid Layout

Each grid item adapts its size to the viewport.

Grid image 1
Grid image 2
Grid image 3
Grid image 4
Grid image 5
Grid image 6
// Responsive grid layout
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  {images.map((image, index) => (
    <Image
      key={index}
      src={image.src}
      alt={image.alt}
      width={400}
      height={400}
      className="w-full h-full object-cover"
      sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
    />
  ))}
</div>

Art Direction (Different Ratios per Screen)

Serve different aspect ratios depending on the viewport.

Mobile: Portrait (3:4)

Portrait for mobile

All screens: responsive aspect ratio

All screen responsive
// Different aspect ratios per screen (art direction)
<div className="w-full aspect-video lg:aspect-[16/9] md:aspect-square sm:aspect-[3/4]">
  <Image
    src="/landing-page/fox.jpg"
    alt="All screen responsive"
    fill
    className="object-cover"
    sizes="100vw"
  />
</div>

// Or use different image sizes per screen type
<Image
  src="/landing-page/fox.jpg"
  width={800}
  height={450}
  className="hidden lg:block" // desktop only
  transforms={{ width: 800, height: 450 }}
/>

<Image
  src="/landing-page/fox.jpg"
  width={600}
  height={600}
  className="hidden md:block lg:hidden" // tablet only
  transforms={{ width: 600, height: 600 }}
/>

Demonstrates how to deliver optimized images across different screen sizes.

Lazy Loading

Live Demo

Default Lazy Loading

By default, `loading="lazy"` defers loading until the image nears the viewport.

Lazy loaded image 1Lazy loaded image 2
// Default lazy loading (implicit)
<Image
  src="/landing-page/fox.jpg"
  alt="Lazy loaded image"
  width={400}
  height={300}
  loading="lazy" // default, can be omitted
/>

Eager Loading

Critical images can use `loading="eager"` to load immediately.

Eager loaded image
// Eager loading (for critical images)
<Image
  src="/landing-page/fox.jpg"
  alt="Eager loaded image"
  width={400}
  height={300}
  loading="eager"
/>

Blur Placeholder

Display a blurred preview while the full image loads for a smoother UX.

Blur placeholder image
// Blur placeholder
<Image
  src="/landing-page/fox.jpg"
  alt="Blur placeholder"
  width={400}
  height={300}
  blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..."
  placeholder="blur"
/>

Color Placeholders

Use solid backgrounds as simple placeholders.

Gray placeholder

Gray placeholder

Blue placeholder

Blue placeholder
// Color placeholder container
<div className="bg-gray-200 p-4 min-h-[200px] flex items-center justify-center">
  <Image
    src="/landing-page/fox.jpg"
    alt="Placeholder example"
    width={300}
    height={200}
  />
</div>

Demonstrates how lazy loading and placeholders improve the image experience.

Priority Loading

Live Demo

Hero Image (Highest Priority)

Top-of-page hero images load instantly when `priority=true`.

Hero image
priority=true: downloads immediately with the page load.
// Hero image - highest priority
<Image
  src="/landing-page/fox.jpg"
  alt="Hero image"
  width={800}
  height={400}
  priority={true}  // load immediately
  className="w-full"
  sizes="100vw"
/>

Important Content Images

Set above-the-fold images to `loading="eager"`.

Important image 1

loading="eager"

// Above-the-fold images
<Image
  src="/landing-page/fox.jpg"
  alt="Important image"
  width={400}
  height={300}
  loading="eager"  // load immediately (lower than priority)
/>

Standard Content Images

Use default lazy loading for below-the-fold images.

Standard image 1

lazy loading

Standard image 2

lazy loading

Standard image 3

lazy loading

Standard image 4

lazy loading

Standard image 5

lazy loading

Standard image 6

lazy loading

// Standard content images
<Image
  src="/landing-page/fox.jpg"
  alt="Standard image"
  width={300}
  height={200}
  loading="lazy"  // default - loads near the viewport
/>

Preloading Strategies Compared

PriorityAttributeWhen to useLoad timing
Highestpriority=trueHero/LCP imagesWith initial page load
Highloading="eager"Above-the-fold imagesImmediate load
Standardloading="lazy"Below-the-fold imagesNear viewport
// Priority-based loading strategy
// 1. Highest priority - LCP image
<Image priority={true} />

// 2. High priority - Above the fold
<Image loading="eager" />

// 3. Standard priority - Below the fold (default)
<Image loading="lazy" />

Conditional Priority Settings

Adjust priority dynamically based on screen size or position.

Priority only on desktop
Desktop priority example
Only the first image prioritized
Conditional image 1Conditional image 2Conditional image 3Conditional image 4
// Conditional priority
{images.map((image, index) => (
  <Image
    key={index}
    src={image.src}
    alt={image.alt}
    priority={index === 0}  // priority only for the first
    loading={index < 3 ? "eager" : "lazy"}  // first 3 eager
  />
))}

// Media query-based priority
const isDesktop = useMediaQuery('(min-width: 1024px)');
<Image
  priority={isDesktop}  // priority on desktop only
/>

Performance Optimization Tips

  • Reserve priority for LCP images only: limit to 1-2 per page
  • Use eager for above-the-fold media: content visible right away
  • Prefer lazy for everything else: avoid unnecessary bandwidth usage
  • Tune the `sizes` attribute: optimize for responsive layouts
  • Use WebP/AVIF formats: reduce file size
// Performance best practices
// ✅ Good example
<Image priority={true} />           // Only one LCP image
<Image loading="eager" />           // 2-3 above-the-fold images
<Image loading="lazy" />            // Everything else

// ❌ Bad example
<Image priority={true} />           // Overusing priority
<Image priority={true} />
<Image priority={true} />
<Image priority={true} />

Shows how to prioritize important images to improve user experience.

Advanced Transformation Effects

Live Demo

Quality Optimization

Balance file size and visual fidelity with various quality settings.

Quality 100%

Quality 100%

High quality

Quality 85%

Quality 85%

High quality

Quality 70%

Quality 70%

Medium quality

Quality 50%

Quality 50%

Low quality

// Optimizing for different quality tiers
<Image quality={100} /> // Highest quality
<Image quality={85} />  // Web standard
<Image quality={70} />  // Mobile standard
<Image quality={50} />  // Low-bandwidth networks

Dynamic Resizing

Use transforms to generate multiple sizes from the original image.

Large image

800×600

Large image

Medium image

400×300

Medium image

Small image

200×150

Small image

Thumbnail

100×100

Thumbnail
// Dynamic resizing
<Image width={800} height={600} />  // High resolution
<Image width={400} height={300} />  // Standard
<Image width={200} height={150} />  // Mobile
<Image width={100} height={100} />  // Thumbnail

Composite Filter Combos

Combine multiple transforms to craft distinctive visual styles.

Vintage Effect
Vintage effect

Grayscale + subtle blur + lower quality

Dramatic Effect
Dramatic effect

Heavy blur + high quality

Mirror Effect
Mirror effect

Flip vertically + flip horizontally

// Composite filter effects
// Vintage effect
<Image transforms={{
  grayscale: true,
  blur: 1,
  quality: 70
}} />

// Dramatic effect
<Image transforms={{
  blur: 3,
  quality: 90
}} />

// Mirror effect
<Image transforms={{
  flip: true,
  flop: true
}} />

Real-time Transform Controls

Adjust the sliders to preview how transforms update instantly.

Preview
Real-time transform preview
Current transforms:
{
  "width": 400,
  "height": 300,
  "quality": 85,
  "blur": 0,
  "grayscale": false,
  "flop": false,
  "flip": false
}
// Real-time transform controls
const [transforms, setTransforms] = useState({
  width: 400,
  height: 300,
  quality: 85,
  blur: 0,
  grayscale: false,
  flop: false,
  flip: false
});

<Image
  src="/fox.jpg"
  alt="Real-time transform"
  width={transforms.width}
  height={transforms.height}
  transforms={transforms}
/>

Art Gallery Effects

Variations of the same image with different artistic treatments.

Original style

Original

Classic style

Classic

Soft style

Soft

Modern style

Modern

Minimal style

Minimal

Pop Art style

Pop Art

Abstract style

Abstract

Vintage style

Vintage

// Art gallery effects
const artStyles = [
  { name: 'Original', transforms: {} },
  { name: 'Classic', transforms: { grayscale: true, quality: 95 } },
  { name: 'Soft', transforms: { blur: 2, quality: 80 } },
  { name: 'Modern', transforms: { flop: true, quality: 90 } },
  { name: 'Minimal', transforms: { grayscale: true, blur: 1 } },
  { name: 'Pop Art', transforms: { flip: true, quality: 100 } },
  { name: 'Abstract', transforms: { blur: 5, grayscale: true } },
  { name: 'Vintage', transforms: { grayscale: true, blur: 1, quality: 60 } }
];

{artStyles.map((style, index) => (
  <Image
    key={index}
    src="/landing-page/fox.jpg"
    alt={`${style.name} style`}
    transforms={style.transforms}
  />
))}

Performance Optimization Tips

  • Choose fitting quality levels: 85% for web, 70-80% for mobile
  • Minimize unnecessary transforms: Apply only what you need to reduce processing time
  • Leverage caching: Identical transform combinations are cached by the CDN
  • Use conditional transforms: Adjust dynamically based on device or network conditions
// Optimized transforms
// Conditional quality setting
const quality = isSlowNetwork ? 60 : 85;

// Device-specific size adjustment
const size = isMobile ? { width: 300, height: 200 } : { width: 600, height: 400 };

// Apply only the necessary transforms
const transforms = {
  quality,
  ...size,
  ...(needsGrayscale && { grayscale: true }),
  ...(needsBlur && { blur: 2 })
};

<Image transforms={transforms} />

Showcases how to leverage complex, advanced image transformation techniques.