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="ja">
<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 heroImage from '@/public/hero.jpg';
<Image
src={heroImage}
alt="ヒーロー"
placeholder="blur"
priority
transforms={{ format: 'auto' }}
/>
動的インポート#
動的に読み込まれる画像の場合:
<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 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
プロパティを使用してください。 -
レスポンシブ画像: レスポンシブレイアウトには常に
sizes
プロパティを提供してください。 -
フォーマット自動: Snapkitが自動的に最適なフォーマットを選択するようにしてください。
トラブルシューティング#
よくある問題#
-
Hydrationの不一致: サーバーとクライアント間で一貫したレンダリングを確認してください。
-
CORS問題:
next.config.js
でdomainsを設定してください。 -
ビルドエラー: すべての静的インポートが有効であることを確認してください。
-
パフォーマンス問題: キャッシュ設定を確認してください。