Guides
Importeren vanuit Lovable
Migreer je Lovable project naar OptimoCMS. Importeer content, afbeeldingen en design tokens met behoud van je design.
Importeren vanuit Lovable
Heb je een website gebouwd in Lovable en wil je deze overzetten naar OptimoCMS voor meer controle, API-toegang en schaalbaarheid? Deze tutorial leidt je door het volledige migratieproces.
In deze tutorial:
- Lovable project verbinden via de SDK en MCP
- Content en afbeeldingen importeren
- Design tokens overnemen van je Lovable design
- Handmatige aanpassingen na import
Vereisten
- Node.js 18+
npm install @optimocms/sdk- De publieke URL van je Lovable project (bijv.
https://jouw-project.lovable.app) - Een OptimoCMS API key
Stap 1 — Lovable project voorbereiden
Voordat je importeert:
- Publiceer je Lovable project — Zorg dat de site live staat op een
.lovable.appURL - Noteer je design keuzes — Kleuren, fonts en border-radius die je wilt behouden
- Controleer afbeeldingen — Alle images moeten publiek toegankelijk zijn
Stap 2 — Import starten via SDK
SDK
import { OptimoCMS } from '@optimocms/sdk';
const client = new OptimoCMS({
apiKey: process.env.OPTIMOCMS_API_KEY!,
});
// Optie A: Import naar een bestaande site
const importResult = await client.import.fromLovable('site_abc123', {
projectUrl: 'https://mijn-restaurant.lovable.app',
name: 'Mijn Restaurant (vanuit Lovable)',
});
console.log(`Import gestart: ${importResult.importId}`);
console.log(`Status: ${importResult.status}`);
console.log(`Voortgang: ${importResult.progress}%`);MCP (Cursor / Claude)
In Cursor of Claude Desktop:
Importeer het Lovable project op https://mijn-restaurant.lovable.app naar mijn OptimoCMS site "site_abc123". Noem het "Mijn Restaurant (vanuit Lovable)".De MCP tool import_from_lovable wordt aangeroepen.
REST
curl -X POST https://api.optimocms.com/v1/sites/$SITE_ID/import/url \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://mijn-restaurant.lovable.app",
"name": "Mijn Restaurant (vanuit Lovable)",
"includeImages": true,
"includeStyles": true,
"source": "lovable"
}'Response:
{
"importId": "imp_abc123",
"siteId": "site_abc123",
"status": "processing",
"progress": 0,
"pagesImported": 0,
"error": null,
"createdAt": "2026-05-26T14:00:00Z"
}Stap 3 — Import status monitoren
De import draait asynchroon. Poll de status tot deze klaar is:
SDK
async function waitForImport(siteId: string, importId: string): Promise<void> {
let status = await client.import.status(siteId, importId);
while (status.status === 'queued' || status.status === 'processing') {
console.log(`Import voortgang: ${status.progress}% (${status.pagesImported} pagina's)`);
await new Promise(resolve => setTimeout(resolve, 2000));
status = await client.import.status(siteId, importId);
}
if (status.status === 'completed') {
console.log(`✓ Import voltooid! ${status.pagesImported} pagina's geïmporteerd`);
} else {
console.error(`✗ Import mislukt: ${status.error}`);
}
}
await waitForImport('site_abc123', importResult.importId);REST
# Poll tot status "completed" is
curl https://api.optimocms.com/v1/sites/$SITE_ID/import/$IMPORT_ID/status \
-H "Authorization: Bearer $API_KEY"Response bij voltooiing:
{
"importId": "imp_abc123",
"siteId": "site_abc123",
"status": "completed",
"progress": 100,
"pagesImported": 5,
"error": null,
"createdAt": "2026-05-26T14:00:00Z",
"completedAt": "2026-05-26T14:02:15Z"
}Stap 4 — Design tokens overnemen
Na de import kun je de design tokens finetunen zodat ze exact overeenkomen met je Lovable design:
SDK
// Bekijk de huidige tokens (automatisch gedetecteerd uit Lovable)
const site = await client.sites.get('site_abc123');
console.log('Gedetecteerde tokens:', site.designTokens);
// Pas aan indien nodig
await client.designTokens.update('site_abc123', {
colorPrimary: '#6366F1', // Lovable's indigo
colorBackground: '#FAFAFA',
colorSurface: '#FFFFFF',
colorText: '#18181B',
colorTextMuted: '#71717A',
fontBody: 'Inter',
fontHeading: 'Inter',
radiusCard: '12px',
radiusButton: '8px',
radiusInput: '8px',
});
console.log('✓ Design tokens aangepast');MCP
Bekijk de design tokens van site "site_abc123" en pas de primary kleur aan naar indigo (#6366F1) met Inter als font.Stap 5 — Content nakijken en aanpassen
Na import wil je de geïmporteerde pagina's controleren:
// Alle geïmporteerde pagina's ophalen
for await (const page of client.pages.list('site_abc123')) {
console.log(`Pagina: ${page.title} (/${page.slug}) — ${page.blocks.length} blocks`);
}
// Specifieke pagina aanpassen
const homePage = (await client.pages.list('site_abc123')).data
.find(p => p.slug === 'home' || p.slug === '/');
if (homePage) {
// SEO optimaliseren
await client.seo.update('site_abc123', homePage.id, {
title: 'Mijn Restaurant — De beste Italiaanse keuken',
description: 'Reserveer nu bij Mijn Restaurant. Verse pasta, pizza en antipasti in hartje Amsterdam.',
});
console.log('✓ SEO bijgewerkt voor homepage');
}Stap 6 — Publiceren
Wanneer alles er goed uitziet, publiceer de site:
SDK
const result = await client.sites.publish('site_abc123');
console.log(`✓ Site gepubliceerd: ${result.status}`);MCP
Publiceer site "site_abc123" naar productie.Volledige migratiescript
import { OptimoCMS } from '@optimocms/sdk';
const client = new OptimoCMS({
apiKey: process.env.OPTIMOCMS_API_KEY!,
});
async function migrateFromLovable(
lovableUrl: string,
siteName: string
): Promise<void> {
console.log(`🚀 Migratie gestart: ${lovableUrl}\n`);
// 1. Nieuwe site aanmaken
const site = await client.sites.create({
name: siteName,
subdomain: siteName.toLowerCase().replace(/[^a-z0-9]+/g, '-'),
language: 'nl',
});
console.log(`✓ Site aangemaakt: ${site.id}`);
// 2. Import starten
const importJob = await client.import.fromLovable(site.id, {
projectUrl: lovableUrl,
name: siteName,
});
console.log(`✓ Import gestart: ${importJob.importId}`);
// 3. Wacht op voltooiing
let status = importJob;
while (status.status === 'queued' || status.status === 'processing') {
await new Promise(resolve => setTimeout(resolve, 3000));
status = await client.import.status(site.id, importJob.importId);
console.log(` Voortgang: ${status.progress}%`);
}
if (status.status === 'failed') {
throw new Error(`Import mislukt: ${status.error}`);
}
console.log(`✓ ${status.pagesImported} pagina's geïmporteerd`);
// 4. Design tokens finetunen
await client.designTokens.update(site.id, {
colorPrimary: '#6366F1',
fontBody: 'Inter',
fontHeading: 'Inter',
radiusCard: '12px',
radiusButton: '8px',
});
console.log('✓ Design tokens ingesteld');
// 5. Publiceren
const publishResult = await client.sites.publish(site.id);
console.log(`✓ Site gepubliceerd (${publishResult.status})`);
console.log(`\n🎉 Klaar! Je site is live op: https://${site.subdomain}.optimocms.com`);
}
migrateFromLovable(
'https://mijn-restaurant.lovable.app',
'Mijn Restaurant'
).catch(error => {
console.error('Migratie mislukt:', error.message);
process.exit(1);
});Wat wordt geïmporteerd?
| Onderdeel | Geïmporteerd | Opmerkingen |
|---|---|---|
| Pagina-structuur | ✓ | Routes worden pagina's |
| Tekst-content | ✓ | Headings, paragraphs, lijsten |
| Afbeeldingen | ✓ | Gekopieerd naar OptimoCMS Storage |
| Kleuren/fonts | ✓ | Omgezet naar design tokens |
| Formulieren | Gedeeltelijk | Basis-velden worden overgenomen |
| Animaties | ✗ | Moet handmatig worden nagebouwd |
| Custom code | ✗ | JavaScript/React niet importeerbaar |
Tips voor een soepele migratie
- Maak een screenshot van je Lovable site vóór de import, als referentie
- Test op sandbox eerst — gebruik een sandbox API key om de import te testen
- Controleer responsive — Check de geïmporteerde pagina's op mobiel
- SEO bewaren — Stel redirects in als je van domein wisselt
- Stap voor stap — Importeer eerst, controleer, pas aan, en publiceer dan pas
Volgende stappen
- Restaurantsite bouwen — Voeg extra features toe aan je geïmporteerde site
- Design tokens — Meer over het token-systeem
- MCP setup voor Lovable — Gebruik MCP vanuit Lovable