Retour au blog
Développement Web
5 septembre 2024
12 min
Équipe Dev Ring

Next.js 14 : Server Actions et les nouvelles fonctionnalités

Explorez les Server Actions de Next.js 14, le nouveau compilateur Turbo et toutes les améliorations qui révolutionnent le développement React.

Next.jsReactServer ActionsTurbopackWeb Development

Next.js 14 marque une étape importante avec la stabilisation des Server Actions et de nombreuses améliorations de performance grâce au nouveau compilateur Turbo.

Server Actions : La révolution du côté serveur

Les Server Actions permettent d'exécuter du code serveur directement depuis les composants clients, simplifiant drastiquement la gestion des formulaires et des mutations de données.

Exemple pratique :

Server Actions : mutation et revalidation

ts
// app/actions.ts
'use server'

import { revalidatePath } from 'next/cache'
import { db } from '@/lib/db'

export async function createPost(formData: FormData) {
  const title = formData.get('title') as string
  const content = formData.get('content') as string
  
  // Validation côté serveur
  if (!title || !content) {
    throw new Error('Titre et contenu requis')
  }
  
  // Insertion en base de données
  await db.post.create({
    data: { title, content }
  })
  
  revalidatePath('/posts')
}

// app/create-post/page.tsx
import { createPost } from '../actions'

export default function CreatePost() {
  return (
    <form action={createPost}>
      <input name="title" placeholder="Titre" required />
      <textarea name="content" placeholder="Contenu" required />
      <button type="submit">Créer</button>
    </form>
  )
}

Avantages des Server Actions :

  • Sécurité renforcée : Validation côté serveur automatique
  • Simplicité : Plus besoin de créer des endpoints API manuellement
  • Performance : Optimisation automatique des requêtes
  • TypeScript : Type-safety de bout en bout

Améliorations de Turbopack

Le compilateur Turbo apporte des gains de performance considérables :

  • 53 % plus rapide pour les rechargements à chaud locaux
  • 94 % plus rapide pour les builds de production
  • Meilleure gestion du tree-shaking

Activation de Turbopack :

Activer Turbopack et ajouter une règle pour SVG

js
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    turbo: {
      rules: {
        '*.svg': {
          loaders: ['@svgr/webpack'],
          as: '*.js',
        },
      },
    },
  },
}

module.exports = nextConfig

Partial Prerendering (Preview)

Une nouvelle approche hybride combinant le rendu statique et dynamique :

Page partiellement pré-rendue (PPR)

tsx
import { Suspense } from 'react'
import { Header } from '@/components/header'
import { Navigation } from '@/components/navigation'
import { Footer } from '@/components/footer'
import { ProductDetails, ProductSkeleton } from '@/components/product'

export default function ProductPage({ params }: { params: { id: string } }) {
  return (
    <div>
      {/* Contenu statique - pré-rendu */}
      <Header />
      <Navigation />
      
      {/* Contenu dynamique - rendu à la demande */}
      <Suspense fallback={<ProductSkeleton />}>
        <ProductDetails id={params.id} />
      </Suspense>
      
      {/* Contenu statique - pré-rendu */}
      <Footer />
    </div>
  )
}

Metadata API améliorée

Meilleure gestion des métadonnées pour le SEO :

Métadonnées statiques et dynamiques

ts
import type { Metadata } from 'next'

// Métadonnées statiques
export const metadata: Metadata = {
  title: 'Mon Article',
  description: "Description de l'article",
  openGraph: {
    images: ['./opengraph-image.jpg'],
  },
}

// Métadonnées dynamiques
export async function generateMetadata(
  { params }: { params: { id: string } }
): Promise<Metadata> {
  const post = await getPost(params.id)
 
  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      images: [post.coverImage],
    },
  }
}

Améliorations du routing

Parallel Routes

Permet d'afficher plusieurs pages simultanément :

Parallel Routes dans un layout

tsx
// app/dashboard/layout.tsx
export default function Layout({
  children,
  analytics,
  team,
}: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
}) {
  return (
    <>
      {children}
      {analytics}
      {team}
    </>
  )
}

Intercepting Routes

Intercepter des routes pour des modales ou overlays :

Intercepting Routes pour une modale photo

tsx
// app/photos/(..)photo/[id]/page.tsx
import Image from 'next/image'
import { Modal } from '@/components/modal'

export default function PhotoModal({ params }: { params: { id: string } }) {
  return (
    <Modal>
      <Image src={`/photos/${params.id}.jpg`} alt="Photo" width={1200} height={800} />
    </Modal>
  )
}

Optimisations d'images avancées

next/image avec placeholder et priority

tsx
import Image from 'next/image'

// Optimisation automatique avec placeholders
export function HeroImage() {
  return (
    <Image
      src="/hero.jpg"
      alt="Hero image"
      width={1200}
      height={600}
      placeholder="blur"
      blurDataURL="data:image/jpeg;base64,..."
      priority
      sizes="(max-width: 768px) 100vw, 50vw"
    />
  )
}

Migration et bonnes pratiques

Pour migrer vers Next.js 14 :

  1. Mise à jour des dépendances
  2. Migration progressive des pages vers les Server Actions
  3. Activation de Turbopack en développement
  4. Tests approfondis des nouvelles fonctionnalités

Commandes de migration :

Mise à jour et scripts

bash
# Installation
npm install next@latest react@latest react-dom@latest

# Mise à jour du package.json
# (exemple)
# {
#   "scripts": {
#     "dev": "next dev --turbo",
#     "build": "next build",
#     "start": "next start"
#   }
# }

Performance et monitoring

Next.js 14 inclut des améliorations pour le monitoring :

Instrumentation côté Node et Edge

ts
// next.config.js
module.exports = {
  experimental: {
    instrumentationHook: true,
  },
}

// instrumentation.ts
export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    await import('./instrumentation.node')
  }
  if (process.env.NEXT_RUNTIME === 'edge') {
    await import('./instrumentation.edge')
  }
}

Nouveaux hooks et utilitaires

useFormStatus et redirect dans une Server Action

tsx
import { useFormStatus } from 'react-dom'
import { redirect } from 'next/navigation'

function SubmitButton() {
  const { pending } = useFormStatus()
  
  return (
    <button type="submit" disabled={pending}>
      {pending ? 'Envoi...' : 'Envoyer'}
    </button>
  )
}

// Dans vos Server Actions
export async function createUser(formData: FormData) {
  // ... logique de création
  redirect('/users')
}

Conclusion

Next.js 14 représente un bond en avant significatif pour l'écosystème React, offrant de nouvelles possibilités tout en maintenant une excellente developer experience.

Les Server Actions simplifient énormément le développement full-stack, tandis que Turbopack améliore considérablement les performances de développement. Ces améliorations, combinées aux nouvelles fonctionnalités de routing et de rendu, font de Next.js 14 un choix incontournable pour les projets React modernes.