Next.js 통합#
@snapkit-studio/nextjs
패키지는 Next.js와의 깊이 있는 통합을 제공하며, Next.js Image 컴포넌트 API와 완전히 호환되면서 Snapkit의 강력한 변환 기능을 추가합니다.
설치#
Next.js 프로젝트에 Snapkit을 설치하세요:
npm install @snapkit-studio/nextjs
# 또는
yarn add @snapkit-studio/nextjs
# 또는
pnpm add @snapkit-studio/nextjs
빠른 시작#
환경 변수 설정#
먼저 .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 설정#
루트 레이아웃에서 Snapkit을 설정하세요:
// app/layout.tsx
import { SnapkitProvider } from '@snapkit-studio/nextjs';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ko">
<body>
<SnapkitProvider
baseUrl="https://snapkit-cdn.snapkit.studio"
organizationName="your-org"
defaultQuality={85}
defaultFormat="auto"
>
{children}
</SnapkitProvider>
</body>
</html>
);
}
Pages Router 설정#
Pages Router의 경우, _app.tsx
에 provider를 추가하세요:
// 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>
);
}
주요 기능#
드롭인 교체#
설정 변경 없이 Next.js Image 컴포넌트를 교체하세요:
// 이전
import Image from 'next/image';
// 이후
import { Image } from '@snapkit-studio/nextjs';
// 사용법은 동일하게 유지
<Image
src="/hero.jpg"
alt="히어로 이미지"
width={800}
height={600}
priority
/>
향상된 변환#
Next.js 기능을 넘어서는 강력한 변환 기능을 추가하세요:
import { Image } from '@snapkit-studio/nextjs';
<Image
src="/product.jpg"
alt="제품 이미지"
width={400}
height={300}
transforms={{
format: 'auto',
quality: 90,
sharpen: true,
blur: 0,
grayscale: false
}}
className="rounded-lg shadow-md"
/>
자동 최적화#
포맷 선택#
브라우저 지원에 따라 자동으로 최신 포맷을 제공하세요:
<Image
src="/photo.jpg"
width={600}
height={400}
transforms={{
format: 'auto' // WebP, AVIF 또는 원본 포맷 제공
}}
/>
품질 조정#
네트워크 인식 품질 최적화:
<Image
src="/high-res.jpg"
width={1200}
height={800}
transforms={{
quality: 'auto' // 연결 속도에 따라 조정
}}
/>
Next.js 전용 기능#
이미지 최적화#
정적 Import#
빌드 타임 최적화와 함께 정적 이미지 import를 완전히 지원:
import heroImage from '@/public/hero.jpg';
<Image
src={heroImage}
alt="히어로"
placeholder="blur"
priority
transforms={{ format: 'auto' }}
/>
동적 Import#
동적으로 로드되는 이미지의 경우:
<Image
src={`/products/${productId}.jpg`}
width={500}
height={500}
transforms={{
format: 'auto',
fit: 'cover'
}}
/>
반응형 이미지#
컨테이너 채우기#
반응형 컨테이너 기반 레이아웃의 경우:
<div className="relative aspect-video">
<Image
src="/banner.jpg"
alt="배너"
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
className="object-cover"
transforms={{ format: 'auto' }}
/>
</div>
아트 디렉션#
다양한 브레이크포인트를 위한 다른 이미지:
<picture>
<source
media="(max-width: 768px)"
srcSet="/mobile-hero.jpg"
/>
<Image
src="/desktop-hero.jpg"
width={1920}
height={1080}
alt="반응형 히어로"
transforms={{ format: 'auto' }}
/>
</picture>
성능 기능#
우선순위 로딩#
LCP 최적화를 위해:
<Image
src="/above-fold.jpg"
width={1200}
height={600}
priority
transforms={{
format: 'auto',
quality: 90
}}
/>
플레이스홀더와 함께 지연 로딩#
부드러운 로딩 경험:
<Image
src="/gallery-image.jpg"
width={400}
height={300}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
loading="lazy"
/>
설정#
next.config.js 설정#
Snapkit을 이미지 최적화 솔루션으로 설정하세요:
// next.config.js
module.exports = {
images: {
domains: ['snapkit-cdn.snapkit.studio'],
loader: 'custom',
loaderFile: './snapkit-loader.js',
},
};
커스텀 로더#
고급 사용 사례를 위한 커스텀 로더 생성:
// 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 기능#
서버 컴포넌트#
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>
);
}
클라이언트 컴포넌트#
클라이언트 사이드 기능과의 원활한 통합:
'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
}}
/>
);
}
고급 사용법#
메타데이터 생성#
SEO와 소셜 공유를 위해:
// 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과 SSG#
Incremental Static Regeneration을 완전히 지원:
// app/blog/[slug]/page.tsx
export const revalidate = 3600; // 매 시간마다 재검증
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#
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
}}
/>
);
}
마이그레이션 가이드#
next/image에서#
최소한의 변경이 필요합니다:
// 1단계: import 업데이트
- import Image from 'next/image';
+ import { Image } from '@snapkit-studio/nextjs';
// 2단계: transforms 추가 (선택사항)
<Image
src="/photo.jpg"
width={500}
height={300}
+ transforms={{ format: 'auto' }}
/>
레거시 Next.js에서#
Next.js 12 이하 버전의 경우:
// 이전 (Next.js 12)
<Image
src="/photo.jpg"
width={500}
height={300}
layout="responsive"
/>
// 이후 (Snapkit 사용)
<Image
src="/photo.jpg"
width={500}
height={300}
sizes="100vw"
style={{
width: '100%',
height: 'auto',
}}
transforms={{ format: 'auto' }}
/>
성능 최적화#
빌드 타임 최적화#
빌드 중에 최적화된 이미지 생성:
// next.config.js
module.exports = {
experimental: {
optimizeImages: true,
},
};
런타임 최적화#
사용자 컨텍스트에 기반한 동적 최적화:
<Image
src="/dynamic.jpg"
width={800}
height={600}
transforms={{
format: 'auto',
quality: typeof window !== 'undefined'
? navigator.connection?.saveData ? 60 : 85
: 85,
}}
/>
모범 사례#
-
App Router 사용: 더 나은 성능을 위해 React Server Components를 활용하세요.
-
캐싱 활성화: 최적화된 이미지를 위한 적절한 캐시 헤더를 설정하세요.
-
Above-the-fold 최적화: 중요한 이미지에는
priority
prop을 사용하세요. -
반응형 이미지: 반응형 레이아웃에는 항상
sizes
prop을 제공하세요. -
자동 포맷: Snapkit이 자동으로 최적의 포맷을 선택하도록 하세요.
문제 해결#
일반적인 문제들#
-
Hydration 불일치: 서버와 클라이언트 간 일관된 렌더링을 확인하세요.
-
CORS 문제:
next.config.js
에서 domains을 설정하세요. -
빌드 오류: 모든 정적 import가 유효한지 확인하세요.
-
성능 문제: 캐싱 설정을 확인하세요.
주요 기능 요약#
- 원활한 Next.js Image 컴포넌트 통합
- 자동 이미지 변환
- 동적 DPR 기반 srcset 생성
- 지능적 포맷 선택 (WebP, AVIF)
- 서버 및 클라이언트 컴포넌트 지원
- TypeScript 정의
- 90%+ 테스트 커버리지