L’architecture headless
En mode headless, WordPress sert uniquement de CMS (gestion de contenu) via son API REST. Le front-end est développé séparément avec un framework JavaScript moderne comme Next.js, Astro ou Nuxt.
Lueur Externe développe des architectures headless WordPress pour les projets nécessitant des performances maximales.
Avantages du headless
| Aspect | WordPress classique | WordPress headless |
|---|---|---|
| Performance | Moyenne | Excellente (SSG/ISR) |
| Sécurité | Surface d’attaque large | API seule exposée |
| Flexibilité front | Limitée au thème | Totale (React, Vue…) |
| SEO | Bon | Excellent (SSG) |
| Édition | Gutenberg complet | Gutenberg + preview |
| Complexité | Faible | Moyenne |
Configurer l’API REST
Endpoints natifs
# Récupérer les articles
GET /wp-json/wp/v2/posts?per_page=10&_embed
# Récupérer un article par slug
GET /wp-json/wp/v2/posts?slug=mon-article&_embed
# Récupérer les pages
GET /wp-json/wp/v2/pages?per_page=100
# Récupérer les catégories
GET /wp-json/wp/v2/categories
Endpoints personnalisés
// Enregistrer un endpoint custom
add_action('rest_api_init', function () {
register_rest_route('lueur/v1', '/featured-posts', [
'methods' => 'GET',
'callback' => function () {
$posts = get_posts([
'meta_key' => 'is_featured',
'meta_value' => '1',
'numberposts' => 6,
]);
return array_map(function ($post) {
return [
'id' => $post->ID,
'title' => $post->post_title,
'slug' => $post->post_slug,
'excerpt' => get_the_excerpt($post),
'image' => get_the_post_thumbnail_url($post, 'large'),
];
}, $posts);
},
'permission_callback' => '__return_true',
]);
});
Intégration Next.js
Client API
// lib/wordpress.ts
const API_URL = process.env.WORDPRESS_API_URL!;
export async function getPosts(page = 1, perPage = 10) {
const res = await fetch(
`${API_URL}/wp-json/wp/v2/posts?page=${page}&per_page=${perPage}&_embed`,
{ next: { revalidate: 3600 } }
);
const posts = await res.json();
const total = parseInt(res.headers.get('X-WP-Total') || '0');
return { posts, total };
}
export async function getPostBySlug(slug: string) {
const res = await fetch(
`${API_URL}/wp-json/wp/v2/posts?slug=${slug}&_embed`,
{ next: { revalidate: 3600 } }
);
const posts = await res.json();
return posts[0] || null;
}
Page article
// app/blog/[slug]/page.tsx
import { getPostBySlug, getPosts } from '@/lib/wordpress';
export async function generateStaticParams() {
const { posts } = await getPosts(1, 100);
return posts.map((post: any) => ({ slug: post.slug }));
}
export default async function BlogPost({ params }: { params: { slug: string } }) {
const post = await getPostBySlug(params.slug);
if (!post) return <div>Article non trouvé</div>;
return (
<article>
<h1 dangerouslySetInnerHTML={{ __html: post.title.rendered }} />
<div dangerouslySetInnerHTML={{ __html: post.content.rendered }} />
</article>
);
}
Preview et ISR
// app/api/preview/route.ts
import { draftMode } from 'next/headers';
import { redirect } from 'next/navigation';
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const secret = searchParams.get('secret');
const slug = searchParams.get('slug');
if (secret !== process.env.PREVIEW_SECRET) {
return new Response('Invalid token', { status: 401 });
}
draftMode().enable();
redirect(`/blog/${slug}`);
}
Conclusion
Le WordPress headless combine la puissance éditoriale de WordPress avec les performances d’un front-end moderne. Lueur Externe conçoit des architectures headless sur mesure pour ses clients.