Aller au contenu

Next.js : styles et assets

app/globals.css, importé dans app/layout.tsx :

:root {
--fond: #fff;
--texte: #111;
}
body {
background: var(--fond);
color: var(--texte);
}

Modules CSS : styles limités au composant.

app/Carte.module.css :

.carte {
border: 1px solid #ddd;
border-radius: 8px;
padding: 1rem;
}
.titre {
font-size: 1.25rem;
}
import styles from './Carte.module.css';
export function Carte({ titre }: { titre: string }) {
return (
<article className={styles.carte}>
<h2 className={styles.titre}>{titre}</h2>
</article>
);
}

Next.js ajoute un suffixe aux noms de classes pour éviter les collisions.

À la création (create-next-app propose Tailwind), ou après coup :

Fenêtre de terminal
npm install tailwindcss @tailwindcss/postcss postcss

postcss.config.mjs :

const config = { plugins: { '@tailwindcss/postcss': {} } };
export default config;

app/globals.css : @import "tailwindcss";. Voir Tailwind : installation, Thème et personnalisation et la variante dark basée sur un attribut (Responsive et états).

import Image from 'next/image';
import photo from '@/public/photo.jpg';
export function Profil() {
return (
<>
<Image
src={photo}
alt="Photo de profil"
width={400}
height={400}
priority
/>
<Image src="/logo.png" alt="Logo" width={120} height={40} />
<Image
src="https://images.exemple.com/a.jpg"
alt="Image distante"
width={800}
height={450}
/>
</>
);
}

next/image produit des formats modernes (WebP, AVIF), plusieurs tailles et le chargement différé, sans décalage de mise en page. Pour les images distantes, déclarer les domaines autorisés :

const config: NextConfig = {
images: {
remotePatterns: [{ protocol: 'https', hostname: 'images.exemple.com' }],
},
};

priority pour l’image principale visible au chargement (LCP). Toujours renseigner alt.

app/layout.tsx
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap',
variable: '--font-inter',
});
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="fr" className={inter.variable}>
<body className="font-sans">{children}</body>
</html>
);
}

next/font télécharge la police au build et l’héberge avec le site : aucune requête vers un service tiers à l’exécution (respect de la vie privée, pas de décalage de mise en page). Pour une police locale : next/font/local.

Avec Tailwind 4, déclarer la variable dans le thème : @theme inline { --font-sans: var(--font-inter); }.

import type { Metadata } from 'next';
export const metadata: Metadata = {
metadataBase: new URL('https://exemple.com'),
title: { default: 'Mon site', template: '%s | Mon site' },
description: 'Description pour les moteurs de recherche',
openGraph: {
title: 'Mon site',
description: 'Description',
url: '/',
siteName: 'Mon site',
locale: 'fr_FR',
type: 'website',
},
alternates: { canonical: '/' },
robots: { index: true, follow: true },
};

Fichiers spéciaux dans app/ :

Fichier Rôle
favicon.ico, icon.png Icônes
opengraph-image.png Image de partage
robots.ts robots.txt généré
sitemap.ts sitemap.xml généré
app/sitemap.ts
import type { MetadataRoute } from 'next';
export default function sitemap(): MetadataRoute.Sitemap {
return [{ url: 'https://exemple.com/', lastModified: new Date() }];
}

public/ est servi à la racine du site : public/robots.txt → /robots.txt, public/images/a.png → /images/a.png. Ne rien y placer de confidentiel. Les fichiers de public/ ne sont pas empreints : ne pas leur donner un cache très long.

Initialiser le thème avant l’affichage pour éviter un flash :

<script
dangerouslySetInnerHTML={{
__html: `try{var t=localStorage.getItem('theme')||(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light');document.documentElement.dataset.theme=t}catch(e){}`,
}}
/>
<html lang="fr" suppressHydrationWarning>

suppressHydrationWarning sur <html> évite l’avertissement d’hydratation causé par l’attribut ajouté avant React. Le script est une chaîne constante (aucune donnée utilisateur) : dangerouslySetInnerHTML est acceptable dans ce cas.

Symptôme Piste
Invalid src prop … hostname is not configured under images Ajouter le domaine à images.remotePatterns
Images non optimisées en output: 'export' images: { unoptimized: true }
Image is missing required "width" property Fournir width et height, ou fill avec un parent positionné
Classes Tailwind sans effet postcss.config.mjs, @import "tailwindcss" dans globals.css (voir Tailwind : dépannage)
Police absente Téléchargement au build : réseau disponible pendant la construction
Flash de thème au chargement Script d’initialisation dans le <head>
Avertissement d’hydratation sur <html> suppressHydrationWarning

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Aucune. Pour l’optimisation d’images en production sur un serveur, le paquet sharp est utilisé par Next.js (installé avec le projet).