Crear un sitio de restaurante
Crea un sitio web de restaurante completo con menú, reservas, reseñas y design tokens usando el SDK de OptimoCMS, MCP y la API REST.
Crear un sitio de restaurante completo
En este tutorial construirás paso a paso un sitio web de restaurante con:
- Página de menú con categorías y platos
- Reservas en línea mediante el sistema de reservas
- Reseñas de clientes
- Design tokens para la identidad visual
- Publicación en producción
Cada paso muestra ejemplos de SDK, MCP y REST lado a lado.
Requisitos previos
- Node.js 18+
- Una clave API de OptimoCMS (créala en el panel bajo Configuración → API)
npm install @optimocms/sdk
Paso 1 — Crear un sitio
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(`Sitio creado: ${site.id}`);MCP (Cursor / Claude)
Crea un nuevo sitio llamado "Ristorante Bella Vista" con subdominio "bellavista" en neerlandés.La herramienta MCP create_site se invoca con:
{
"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"
}'Paso 2 — Instalar una plantilla
Elige una plantilla de restaurante de la biblioteca e instálala en tu sitio.
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(`Plantilla instalada, ${result.pagesCreated.length} páginas creadas`);MCP
Instala la plantilla de restaurante en el sitio "bellavista" con un color primario rojo oscuro (#8B0000) y Playfair Display como fuente de títulos.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"
}
}'Paso 3 — Rellenar la página del menú
Crea una página de menú con categorías y platos como bloques de contenido.
SDK
const menuPage = await client.pages.create(site.id, {
title: 'Menú',
slug: 'menu',
status: 'draft',
blocks: [
{
type: 'Hero',
props: {
title: 'Nuestro Menú',
subtitle: 'Platos italianos frescos, preparados diariamente',
backgroundImage: '/images/kitchen.jpg',
},
},
{
type: 'MenuCategory',
props: {
title: "Antipasti",
items: [
{ name: 'Bruschetta al Pomodoro', price: '9,50 €', description: 'Pan tostado con tomate y albahaca' },
{ name: 'Carpaccio di Manzo', price: '14,00 €', description: 'Finas lonchas de ternera con rúcula y parmesano' },
{ name: 'Burrata con Prosciutto', price: '16,50 €', description: 'Burrata cremosa con jamón de Parma' },
],
},
},
{
type: 'MenuCategory',
props: {
title: "Primi Piatti",
items: [
{ name: 'Spaghetti Carbonara', price: '16,00 €', description: 'Clásica con guanciale y pecorino' },
{ name: 'Risotto ai Funghi Porcini', price: '18,50 €', description: 'Risotto cremoso con boletus' },
{ name: 'Tagliatelle al Ragù', price: '17,00 €', description: 'Pasta fresca con salsa de carne cocida lentamente' },
],
},
},
{
type: 'MenuCategory',
props: {
title: "Dolci",
items: [
{ name: 'Tiramisù della Casa', price: '9,00 €', description: 'Hecho en casa según la receta de la abuela' },
{ name: 'Panna Cotta', price: '8,50 €', description: 'Con frutas de temporada y coulis' },
],
},
},
],
});
console.log(`Página de menú creada: ${menuPage.id}`);MCP
Crea una página de menú en el sitio "bellavista" con las categorías Antipasti, Primi Piatti y Dolci. Añade 2-3 platos por categoría con nombre, precio y descripción breve.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": "Menú",
"slug": "menu",
"status": "draft",
"blocks": [
{
"type": "Hero",
"props": { "title": "Nuestro Menú", "subtitle": "Platos italianos frescos" }
},
{
"type": "MenuCategory",
"props": {
"title": "Antipasti",
"items": [
{ "name": "Bruschetta al Pomodoro", "price": "9,50 €" },
{ "name": "Carpaccio di Manzo", "price": "14,00 €" }
]
}
}
]
}'Paso 4 — Activar las reservas
Configura el sistema de reservas para que los clientes puedan reservar en línea.
SDK
const bookingPage = await client.pages.create(site.id, {
title: 'Reservar',
slug: 'reservar',
status: 'published',
blocks: [
{
type: 'Hero',
props: { title: 'Reservar una mesa', subtitle: 'Elige tu fecha y hora preferidas' },
},
{
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} horarios disponibles`);
const booking = await client.booking.create(site.id, {
serviceId: 'dinner',
date: '2026-06-15',
startTime: '19:00',
customer: {
name: 'Juan García',
email: 'juan@ejemplo.es',
phone: '+34612345678',
},
});
console.log(`Reserva confirmada: ${booking.id} (${booking.status})`);MCP
Activa las reservas en el sitio "bellavista". Crea una página de reservas con un widget de reserva para el servicio de cena.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": "Juan García",
"email": "juan@ejemplo.es"
}
}'Paso 5 — Configurar design tokens
Personaliza la identidad visual con design tokens — se aplican en todas las páginas.
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 actualizados: ${tokens.updatedAt}`);MCP
Actualiza los design tokens del sitio "bellavista": color primario rojo oscuro #8B0000, fondo blanco cálido #FFF8F0, fuente de títulos Playfair Display, fuente de cuerpo 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"
}'Paso 6 — Publicar
Publica el sitio en producción para que los visitantes puedan acceder.
SDK
const publishResult = await client.sites.publish(site.id);
if (publishResult.status === 'queued' || publishResult.status === 'deploying') {
console.log(`¡El sitio se está publicando! Deploy ID: ${publishResult.deployId}`);
console.log(`En línea en: https://bellavista.optimocms.com`);
}MCP
Publica el sitio "bellavista" en producción.REST
curl -X POST https://api.optimocms.com/v1/sites/$SITE_ID/publish \
-H "Authorization: Bearer $API_KEY"Respuesta:
{
"siteId": "site_abc123",
"status": "deploying",
"deployId": "dpl_xyz789"
}Script completo
Aquí el script completo que combina todos los pasos:
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: 'Menú',
slug: 'menu',
status: 'published',
blocks: [
{ type: 'Hero', props: { title: 'Nuestro Menú' } },
{ type: 'MenuCategory', props: { title: 'Antipasti', items: [
{ name: 'Bruschetta', price: '9,50 €' },
{ name: 'Carpaccio', price: '14,00 €' },
]}},
],
});
await client.pages.create(site.id, {
title: 'Reservar',
slug: 'reservar',
status: 'published',
blocks: [
{ type: 'BookingWidget', props: { serviceId: 'dinner' } },
],
});
const result = await client.sites.publish(site.id);
console.log(`✓ Sitio en línea en https://bellavista.optimocms.com (${result.status})`);
}
buildRestaurantSite().catch(console.error);Siguientes pasos
- Design tokens — Más información sobre el sistema de tokens
- Gestionar reservas — Referencia completa de la API de reservas
- Automatizar multi-sitio — El mismo flujo para 50 restaurantes