Créer un site de restaurant
Créez un site web de restaurant complet avec menu, réservations, avis et design tokens via le SDK OptimoCMS, MCP et l'API REST.
Créer un site de restaurant complet
Dans ce tutoriel, vous allez construire étape par étape un site web de restaurant avec :
- Page de menu avec catégories et plats
- Réservations en ligne via le système de réservation
- Avis clients
- Design tokens pour l'identité visuelle
- Publication en production
Chaque étape montre des exemples SDK, MCP et REST côte à côte.
Prérequis
- Node.js 18+
- Une clé API OptimoCMS (créez-en une dans le tableau de bord sous Paramètres → API)
npm install @optimocms/sdk
Étape 1 — Créer un site
SDK
import { OptimoCMS } from '@optimocms/sdk';
const client = new OptimoCMS({
apiKey: process.env.OPTIMOCMS_API_KEY!,
});
const site = await client.sites.create({
name: 'Ristorante Bella Vista',
subdomain: 'bellavista',
language: 'nl',
});
console.log(`Site créé : ${site.id}`);MCP (Cursor / Claude)
Créez un nouveau site nommé "Ristorante Bella Vista" avec le sous-domaine "bellavista" en néerlandais.L'outil MCP create_site est appelé avec :
{
"name": "Ristorante Bella Vista",
"subdomain": "bellavista",
"language": "nl"
}REST
curl -X POST https://api.optimocms.com/v1/sites \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Ristorante Bella Vista",
"subdomain": "bellavista",
"language": "nl"
}'Étape 2 — Installer un template
Choisissez un template de restaurant dans la bibliothèque et installez-le sur votre site.
SDK
const templates = await client.templates.list({ category: 'restaurant' });
const template = templates.data[0];
const result = await client.templates.install(site.id, {
templateId: template.id,
designTokens: {
colorPrimary: '#8B0000',
fontHeading: 'Playfair Display',
fontBody: 'Inter',
radiusCard: '12px',
radiusButton: '8px',
},
});
console.log(`Template installé, ${result.pagesCreated.length} pages créées`);MCP
Installez le template restaurant sur le site "bellavista" avec une couleur primaire rouge foncé (#8B0000) et Playfair Display comme police de titre.REST
curl -X POST https://api.optimocms.com/v1/sites/$SITE_ID/templates/install \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "tmpl_restaurant_classic",
"designTokens": {
"colorPrimary": "#8B0000",
"fontHeading": "Playfair Display",
"fontBody": "Inter",
"radiusCard": "12px",
"radiusButton": "8px"
}
}'Étape 3 — Remplir la page du menu
Créez une page de menu avec des catégories et des plats sous forme de blocs de contenu.
SDK
const menuPage = await client.pages.create(site.id, {
title: 'Menu',
slug: 'menu',
status: 'draft',
blocks: [
{
type: 'Hero',
props: {
title: 'Notre Menu',
subtitle: 'Plats italiens frais, préparés quotidiennement',
backgroundImage: '/images/kitchen.jpg',
},
},
{
type: 'MenuCategory',
props: {
title: "Antipasti",
items: [
{ name: 'Bruschetta al Pomodoro', price: '9,50 €', description: 'Pain grillé avec tomate et basilic' },
{ name: 'Carpaccio di Manzo', price: '14,00 €', description: 'Fines tranches de bœuf avec roquette et parmesan' },
{ name: 'Burrata con Prosciutto', price: '16,50 €', description: 'Burrata crémeuse avec jambon de Parme' },
],
},
},
{
type: 'MenuCategory',
props: {
title: "Primi Piatti",
items: [
{ name: 'Spaghetti Carbonara', price: '16,00 €', description: 'Classique avec guanciale et pecorino' },
{ name: 'Risotto ai Funghi Porcini', price: '18,50 €', description: 'Risotto crémeux aux cèpes' },
{ name: 'Tagliatelle al Ragù', price: '17,00 €', description: 'Pâtes fraîches avec sauce à la viande mijotée' },
],
},
},
{
type: 'MenuCategory',
props: {
title: "Dolci",
items: [
{ name: 'Tiramisù della Casa', price: '9,00 €', description: 'Fait maison selon la recette de grand-mère' },
{ name: 'Panna Cotta', price: '8,50 €', description: 'Avec fruits de saison et coulis' },
],
},
},
],
});
console.log(`Page menu créée : ${menuPage.id}`);MCP
Créez une page de menu sur le site "bellavista" avec les catégories Antipasti, Primi Piatti et Dolci. Ajoutez 2-3 plats par catégorie avec nom, prix et courte description.REST
curl -X POST https://api.optimocms.com/v1/sites/$SITE_ID/pages \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Menu",
"slug": "menu",
"status": "draft",
"blocks": [
{
"type": "Hero",
"props": { "title": "Notre Menu", "subtitle": "Plats italiens frais" }
},
{
"type": "MenuCategory",
"props": {
"title": "Antipasti",
"items": [
{ "name": "Bruschetta al Pomodoro", "price": "9,50 €" },
{ "name": "Carpaccio di Manzo", "price": "14,00 €" }
]
}
}
]
}'Étape 4 — Activer les réservations
Configurez le système de réservation pour que les clients puissent réserver en ligne.
SDK
const bookingPage = await client.pages.create(site.id, {
title: 'Réservation',
slug: 'reservation',
status: 'published',
blocks: [
{
type: 'Hero',
props: { title: 'Réserver une table', subtitle: 'Choisissez votre date et heure préférées' },
},
{
type: 'BookingWidget',
props: { serviceId: 'dinner', showStaff: false, showBranch: false },
},
],
});
const slots = await client.booking.getSlots(site.id, {
serviceId: 'dinner',
date: '2026-06-15',
});
console.log(`${slots.slots.filter(s => s.available).length} créneaux disponibles`);
const booking = await client.booking.create(site.id, {
serviceId: 'dinner',
date: '2026-06-15',
startTime: '19:00',
customer: {
name: 'Jean Dupont',
email: 'jean@exemple.fr',
phone: '+33612345678',
},
});
console.log(`Réservation confirmée : ${booking.id} (${booking.status})`);MCP
Activez les réservations sur le site "bellavista". Créez une page de réservation avec un widget de réservation pour le service dîner.REST
curl https://api.optimocms.com/v1/sites/$SITE_ID/booking/slots?serviceId=dinner&date=2026-06-15 \
-H "Authorization: Bearer $API_KEY"
curl -X POST https://api.optimocms.com/v1/sites/$SITE_ID/booking \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"serviceId": "dinner",
"date": "2026-06-15",
"startTime": "19:00",
"customer": {
"name": "Jean Dupont",
"email": "jean@exemple.fr"
}
}'Étape 5 — Configurer les design tokens
Personnalisez l'identité visuelle avec les design tokens — ils s'appliquent à toutes les pages.
SDK
const tokens = await client.designTokens.update(site.id, {
colorPrimary: '#8B0000',
colorBackground: '#FFF8F0',
colorSurface: '#FFFFFF',
colorText: '#1A1A1A',
colorTextMuted: '#6B7280',
fontHeading: 'Playfair Display',
fontBody: 'Inter',
radiusCard: '12px',
radiusButton: '8px',
radiusInput: '6px',
});
console.log(`Design tokens mis à jour : ${tokens.updatedAt}`);MCP
Mettez à jour les design tokens du site "bellavista" : couleur primaire rouge foncé #8B0000, fond blanc chaud #FFF8F0, police de titre Playfair Display, police de corps Inter.REST
curl -X PUT https://api.optimocms.com/v1/sites/$SITE_ID/design-tokens \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"colorPrimary": "#8B0000",
"colorBackground": "#FFF8F0",
"colorSurface": "#FFFFFF",
"colorText": "#1A1A1A",
"fontHeading": "Playfair Display",
"fontBody": "Inter",
"radiusCard": "12px",
"radiusButton": "8px"
}'Étape 6 — Publier
Publiez le site en production pour que les visiteurs puissent y accéder.
SDK
const publishResult = await client.sites.publish(site.id);
if (publishResult.status === 'queued' || publishResult.status === 'deploying') {
console.log(`Le site est en cours de publication ! Deploy ID : ${publishResult.deployId}`);
console.log(`En ligne sur : https://bellavista.optimocms.com`);
}MCP
Publiez le site "bellavista" en production.REST
curl -X POST https://api.optimocms.com/v1/sites/$SITE_ID/publish \
-H "Authorization: Bearer $API_KEY"Réponse :
{
"siteId": "site_abc123",
"status": "deploying",
"deployId": "dpl_xyz789"
}Script complet
Voici le script complet combinant toutes les étapes :
import { OptimoCMS } from '@optimocms/sdk';
const client = new OptimoCMS({
apiKey: process.env.OPTIMOCMS_API_KEY!,
});
async function buildRestaurantSite() {
const site = await client.sites.create({
name: 'Ristorante Bella Vista',
subdomain: 'bellavista',
language: 'nl',
});
const templates = await client.templates.list({ category: 'restaurant' });
await client.templates.install(site.id, {
templateId: templates.data[0].id,
});
await client.designTokens.update(site.id, {
colorPrimary: '#8B0000',
colorBackground: '#FFF8F0',
fontHeading: 'Playfair Display',
fontBody: 'Inter',
radiusCard: '12px',
radiusButton: '8px',
});
await client.pages.create(site.id, {
title: 'Menu',
slug: 'menu',
status: 'published',
blocks: [
{ type: 'Hero', props: { title: 'Notre Menu' } },
{ type: 'MenuCategory', props: { title: 'Antipasti', items: [
{ name: 'Bruschetta', price: '9,50 €' },
{ name: 'Carpaccio', price: '14,00 €' },
]}},
],
});
await client.pages.create(site.id, {
title: 'Réservation',
slug: 'reservation',
status: 'published',
blocks: [
{ type: 'BookingWidget', props: { serviceId: 'dinner' } },
],
});
const result = await client.sites.publish(site.id);
console.log(`✓ Site en ligne sur https://bellavista.optimocms.com (${result.status})`);
}
buildRestaurantSite().catch(console.error);Prochaines étapes
- Design tokens — En savoir plus sur le système de tokens
- Gérer les réservations — Référence complète de l'API de réservation
- Automatiser multi-sites — Le même flux pour 50 restaurants