Next.js Integration#
The @snapkit-studio/nextjs
package provides deep integration with Next.js, offering full compatibility with Next.js Image component APIs while adding Snapkit's powerful transformation capabilities.
Installation#
Install Snapkit for your Next.js project:
npm install @snapkit-studio/nextjs
# or
yarn add @snapkit-studio/nextjs
# or
pnpm add @snapkit-studio/nextjs
Quick Start#
Environment Configuration#
First, set up your environment variables in .env.local
:
NEXT_PUBLIC_SNAPKIT_ORGANIZATION_NAME=your-organization-name
NEXT_PUBLIC_SNAPKIT_DEFAULT_QUALITY=85
NEXT_PUBLIC_SNAPKIT_DEFAULT_OPTIMIZE_FORMAT=auto
App Router Setup#
Configure Snapkit in your root layout:
// app/layout.tsx
import { SnapkitProvider } from '@snapkit-studio/nextjs';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<SnapkitProvider
baseUrl="https://snapkit-cdn.snapkit.studio"
organizationName="your-org"
defaultQuality={85}
defaultFormat="auto"
>
{children}
</SnapkitProvider>
</body>
</html>
);
}
Pages Router Setup#
For Pages Router, add the provider to _app.tsx
:
// pages/_app.tsx
import { SnapkitProvider } from '@snapkit-studio/nextjs';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<SnapkitProvider
baseUrl="https://snapkit-cdn.snapkit.studio"
organizationName="your-org"
defaultQuality={85}
defaultFormat="auto"
>
<Component {...pageProps} />
</SnapkitProvider>
);
}
Key Features#
Drop-in Replacement#
Replace Next.js Image component with zero configuration changes:
// Before
import Image from 'next/image';
// After
import { Image } from '@snapkit-studio/nextjs';
// Usage remains the same
<Image
src="/hero.jpg"
alt="Hero image"
width={800}
height={600}
priority
/>
Basic Usage Example#
Simple usage with automatic optimization:
import { Image } from '@snapkit-studio/nextjs';
<Image
src="/photo.jpg"
width={800}
height={600}
alt="Photo"
transforms={{
format: 'auto',
quality: 85
}}
/>
Enhanced Transformations#
Beyond Next.js capabilities, add powerful transformations:
import { Image } from '@snapkit-studio/nextjs';
<Image
src="/product.jpg"
alt="Product image"
width={400}
height={300}
transforms={{
format: 'auto',
quality: 90,
sharpen: true,
blur: 0,
grayscale: false
}}
className="rounded-lg shadow-md"
/>
Automatic Optimization#
Format Selection#
Automatically serve modern formats based on browser support:
<Image
src="/photo.jpg"
width={600}
height={400}
transforms={{
format: 'auto' // Serves WebP, AVIF, or original format
}}
/>
Quality Adjustment#
Network-aware quality optimization:
<Image
src="/high-res.jpg"
width={1200}
height={800}
transforms={{
quality: 'auto' // Adjusts based on connection speed
}}
/>
Next.js Specific Features#
Image Optimization#
Static Imports#
Full support for static image imports with build-time optimization:
import heroImage from '@/public/hero.jpg';
<Image
src={heroImage}
alt="Hero"
placeholder="blur"
priority
transforms={{ format: 'auto' }}
/>
Dynamic Imports#
For dynamically loaded images:
<Image
src={`/products/${productId}.jpg`}
width={500}
height={500}
transforms={{
format: 'auto',
fit: 'cover'
}}
/>
Responsive Images#
Fill Container#
For responsive container-based layouts:
<div className="relative aspect-video">
<Image
src="/banner.jpg"
alt="Banner"
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
className="object-cover"
transforms={{ format: 'auto' }}
/>
</div>
Art Direction#
Different images for different breakpoints:
<picture>
<source
media="(max-width: 768px)"
srcSet="/mobile-hero.jpg"
/>
<Image
src="/desktop-hero.jpg"
width={1920}
height={1080}
alt="Responsive hero"
transforms={{ format: 'auto' }}
/>
</picture>
Performance Features#
Priority Loading#
For LCP optimization:
<Image
src="/above-fold.jpg"
width={1200}
height={600}
priority
transforms={{
format: 'auto',
quality: 90
}}
/>
Lazy Loading with Placeholder#
Smooth loading experience:
<Image
src="/gallery-image.jpg"
width={400}
height={300}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
loading="lazy"
/>
Configuration#
next.config.js Setup#
Configure Snapkit as your image optimization solution:
// next.config.js
module.exports = {
images: {
domains: ['snapkit-cdn.snapkit.studio'],
loader: 'custom',
loaderFile: './snapkit-loader.js',
},
};
Custom Loader#
Create a custom loader for advanced use cases:
// snapkit-loader.js
export default function snapkitLoader({ src, width, quality }) {
const url = new URL(`https://your-org-cdn.snapkit.studio/${src}`);
const params = {
w: width,
q: quality || 75,
auto: 'format',
};
Object.keys(params).forEach(key =>
url.searchParams.set(key, params[key])
);
return url.href;
}
App Router Features#
Server Components#
Full support for React Server Components:
// app/gallery/page.tsx
import { Image } from '@snapkit-studio/nextjs';
export default async function Gallery() {
const images = await fetchImages();
return (
<div className="grid grid-cols-3 gap-4">
{images.map((img) => (
<Image
key={img.id}
src={img.url}
width={400}
height={300}
alt={img.alt}
transforms={{ format: 'auto' }}
/>
))}
</div>
);
}
Client Components#
Seamless integration with client-side features:
'use client';
import { useState } from 'react';
import { Image } from '@snapkit-studio/nextjs';
export default function InteractiveGallery() {
const [selectedImage, setSelectedImage] = useState(0);
return (
<Image
src={images[selectedImage]}
width={800}
height={600}
transforms={{
format: 'auto',
quality: 90
}}
/>
);
}
Advanced Usage#
Metadata Generation#
For SEO and social sharing:
// app/products/[id]/page.tsx
import { Metadata } from 'next';
export async function generateMetadata({ params }): Promise<Metadata> {
const product = await getProduct(params.id);
return {
openGraph: {
images: [{
url: `https://your-cdn.snapkit.studio/${product.image}?w=1200&h=630&fit=cover`,
width: 1200,
height: 630,
}],
},
};
}
ISR and SSG#
Full support for Incremental Static Regeneration:
// app/blog/[slug]/page.tsx
export const revalidate = 3600; // Revalidate every hour
export default async function BlogPost({ params }) {
const post = await getPost(params.slug);
return (
<Image
src={post.featuredImage}
width={1200}
height={600}
alt={post.title}
priority
transforms={{ format: 'auto' }}
/>
);
}
Edge Runtime#
Optimized for Edge runtime:
export const runtime = 'edge';
export default function EdgeOptimizedPage() {
return (
<Image
src="/edge-optimized.jpg"
width={600}
height={400}
transforms={{
format: 'auto',
quality: 85
}}
/>
);
}
Migration Guide#
From next/image#
Minimal changes required:
// Step 1: Update import
- import Image from 'next/image';
+ import { Image } from '@snapkit-studio/nextjs';
// Step 2: Add transforms (optional)
<Image
src="/photo.jpg"
width={500}
height={300}
+ transforms={{ format: 'auto' }}
/>
From Legacy Next.js#
For Next.js 12 and earlier:
// Before (Next.js 12)
<Image
src="/photo.jpg"
width={500}
height={300}
layout="responsive"
/>
// After (with Snapkit)
<Image
src="/photo.jpg"
width={500}
height={300}
sizes="100vw"
style={{
width: '100%',
height: 'auto',
}}
transforms={{ format: 'auto' }}
/>
Performance Optimization#
Build-Time Optimization#
Generate optimized images during build:
// next.config.js
module.exports = {
experimental: {
optimizeImages: true,
},
};
Runtime Optimization#
Dynamic optimization based on user context:
<Image
src="/dynamic.jpg"
width={800}
height={600}
transforms={{
format: 'auto',
quality: typeof window !== 'undefined'
? navigator.connection?.saveData ? 60 : 85
: 85,
}}
/>
Best Practices#
-
Use App Router: Take advantage of React Server Components for better performance.
-
Enable Caching: Configure proper cache headers for optimized images.
-
Optimize Above-Fold: Use
priority
prop for critical images. -
Responsive Images: Always provide
sizes
prop for responsive layouts. -
Format Auto: Let Snapkit choose the best format automatically.
Troubleshooting#
Common Issues#
-
Hydration Mismatch: Ensure consistent rendering between server and client.
-
CORS Issues: Configure domains in
next.config.js
. -
Build Errors: Check that all static imports are valid.
-
Performance Issues: Verify caching configuration.
Key Features Summary#
- Seamless Next.js Image component integration
- Automatic image transformation
- Dynamic DPR-based srcset generation
- Intelligent format selection (WebP, AVIF)
- Server and client component support
- TypeScript definitions
- 90%+ test coverage