Intégration Next.js#

Le package @snapkit-studio/nextjs fournit une intégration profonde avec Next.js, offrant une compatibilité complète avec les APIs des composants Next.js Image tout en ajoutant les puissantes capacités de transformation de Snapkit.

Installation#

Installez Snapkit pour votre projet Next.js :

npm install @snapkit-studio/nextjs
# ou
yarn add @snapkit-studio/nextjs
# ou
pnpm add @snapkit-studio/nextjs

Démarrage Rapide#

Configuration de l'Environnement#

D'abord, configurez vos variables d'environnement dans .env.local :

NEXT_PUBLIC_SNAPKIT_ORGANIZATION_NAME=your-organization-name
NEXT_PUBLIC_SNAPKIT_DEFAULT_QUALITY=85
NEXT_PUBLIC_SNAPKIT_DEFAULT_OPTIMIZE_FORMAT=auto

Configuration App Router#

Configurez Snapkit dans votre layout racine :

// app/layout.tsx
import { SnapkitProvider } from '@snapkit-studio/nextjs';
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="fr">
      <body>
        <SnapkitProvider
          baseUrl="https://snapkit-cdn.snapkit.studio"
          organizationName="your-org"
          defaultQuality={85}
          defaultFormat="auto"
        >
          {children}
        </SnapkitProvider>
      </body>
    </html>
  );
}

Configuration Pages Router#

Pour Pages Router, ajoutez le provider à _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>
  );
}

Utilisation de Base#

La façon la plus simple d'utiliser Snapkit dans votre application Next.js :

import { Image } from '@snapkit-studio/nextjs';
 
function MyComponent() {
  return (
    <Image
      src="/hero.jpg"
      alt="Image Hero"
      width={800}
      height={600}
      priority
      transforms={{ format: 'auto' }}
    />
  );
}

Fonctionnalités Principales#

Remplacement Direct#

Remplacez le composant Next.js Image sans changement de configuration :

// Avant
import Image from 'next/image';
 
// Après
import { Image } from '@snapkit-studio/nextjs';
 
// L'utilisation reste la même
<Image
  src="/hero.jpg"
  alt="Image hero"
  width={800}
  height={600}
  priority
/>

Transformations Améliorées#

Ajoutez de puissantes transformations au-delà des capacités de Next.js :

import { Image } from '@snapkit-studio/nextjs';
 
<Image
  src="/product.jpg"
  alt="Image produit"
  width={400}
  height={300}
  transforms={{
    format: 'auto',
    quality: 90,
    sharpen: true,
    blur: 0,
    grayscale: false
  }}
  className="rounded-lg shadow-md"
/>

Optimisation Automatique#

Sélection de Format#

Servez automatiquement des formats modernes basés sur le support du navigateur :

<Image
  src="/photo.jpg"
  width={600}
  height={400}
  transforms={{
    format: 'auto' // Sert WebP, AVIF ou format original
  }}
/>

Ajustement de Qualité#

Optimisation de qualité consciente du réseau :

<Image
  src="/high-res.jpg"
  width={1200}
  height={800}
  transforms={{
    quality: 'auto' // S'ajuste selon la vitesse de connexion
  }}
/>

Fonctionnalités Spécifiques à Next.js#

Optimisation d'Images#

Imports Statiques#

Support complet pour les imports d'images statiques avec optimisation build-time :

import heroImage from '@/public/hero.jpg';
 
<Image
  src={heroImage}
  alt="Hero"
  placeholder="blur"
  priority
  transforms={{ format: 'auto' }}
/>

Imports Dynamiques#

Pour les images chargées dynamiquement :

<Image
  src={`/products/${productId}.jpg`}
  width={500}
  height={500}
  transforms={{
    format: 'auto',
    fit: 'cover'
  }}
/>

Images Responsives#

Remplir le Conteneur#

Pour les layouts responsifs basés sur conteneur :

<div className="relative aspect-video">
  <Image
    src="/banner.jpg"
    alt="Bannière"
    fill
    sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
    className="object-cover"
    transforms={{ format: 'auto' }}
  />
</div>

Direction Artistique#

Différentes images pour différents breakpoints :

<picture>
  <source
    media="(max-width: 768px)"
    srcSet="/mobile-hero.jpg"
  />
  <Image
    src="/desktop-hero.jpg"
    width={1920}
    height={1080}
    alt="Hero responsif"
    transforms={{ format: 'auto' }}
  />
</picture>

Fonctionnalités de Performance#

Priority Loading#

Pour l'optimisation LCP :

<Image
  src="/above-fold.jpg"
  width={1200}
  height={600}
  priority
  transforms={{
    format: 'auto',
    quality: 90
  }}
/>

Lazy Loading avec Placeholder#

Expérience de chargement fluide :

<Image
  src="/gallery-image.jpg"
  width={400}
  height={300}
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
  loading="lazy"
/>

Configuration#

Configuration next.config.js#

Configurez Snapkit comme votre solution d'optimisation d'images :

// next.config.js
module.exports = {
  images: {
    domains: ['snapkit-cdn.snapkit.studio'],
    loader: 'custom',
    loaderFile: './snapkit-loader.js',
  },
};

Loader Personnalisé#

Créez un loader personnalisé pour des cas d'usage avancés :

// 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;
}

Fonctionnalités App Router#

Composants Serveur#

Support complet pour 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>
  );
}

Composants Client#

Intégration transparente avec les fonctionnalités côté client :

'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
      }}
    />
  );
}

Usage Avancé#

Génération de Métadonnées#

Pour le SEO et le partage social :

// 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 et SSG#

Support complet pour Incremental Static Regeneration :

// app/blog/[slug]/page.tsx
export const revalidate = 3600; // Revalider toutes les heures
 
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#

Optimisé pour 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
      }}
    />
  );
}

Guide de Migration#

Depuis next/image#

Changements minimaux requis :

// Étape 1 : Mettre à jour l'import
- import Image from 'next/image';
+ import { Image } from '@snapkit-studio/nextjs';
 
// Étape 2 : Ajouter transforms (optionnel)
<Image
  src="/photo.jpg"
  width={500}
  height={300}
+ transforms={{ format: 'auto' }}
/>

Depuis Next.js Legacy#

Pour Next.js 12 et antérieur :

// Avant (Next.js 12)
<Image
  src="/photo.jpg"
  width={500}
  height={300}
  layout="responsive"
/>
 
// Après (avec Snapkit)
<Image
  src="/photo.jpg"
  width={500}
  height={300}
  sizes="100vw"
  style={{
    width: '100%',
    height: 'auto',
  }}
  transforms={{ format: 'auto' }}
/>

Optimisation de Performance#

Optimisation Build-Time#

Générer des images optimisées pendant le build :

// next.config.js
module.exports = {
  experimental: {
    optimizeImages: true,
  },
};

Optimisation Runtime#

Optimisation dynamique basée sur le contexte utilisateur :

<Image
  src="/dynamic.jpg"
  width={800}
  height={600}
  transforms={{
    format: 'auto',
    quality: typeof window !== 'undefined'
      ? navigator.connection?.saveData ? 60 : 85
      : 85,
  }}
/>

Meilleures Pratiques#

  1. Utiliser App Router : Tirez parti des React Server Components pour de meilleures performances.

  2. Activer le Caching : Configurez des en-têtes de cache appropriés pour les images optimisées.

  3. Optimiser Above-the-fold : Utilisez la prop priority pour les images critiques.

  4. Images Responsives : Toujours fournir la prop sizes pour les layouts responsifs.

  5. Format Auto : Laissez Snapkit choisir automatiquement le meilleur format.

Dépannage#

Problèmes Communs#

  1. Mismatch d'Hydratation : Assurez un rendu cohérent entre serveur et client.

  2. Problèmes CORS : Configurez les domaines dans next.config.js.

  3. Erreurs de Build : Vérifiez que tous les imports statiques sont valides.

  4. Problèmes de Performance : Vérifiez la configuration de cache.

Résumé des Fonctionnalités Principales#

  • Intégration transparente du composant Next.js Image
  • Transformation automatique d'images
  • Génération dynamique de srcset basée sur DPR
  • Sélection intelligente de format (WebP, AVIF)
  • Support des composants serveur et client
  • Définitions TypeScript
  • Couverture de tests de 90%+

Ressources#