OptimoCMSDocs
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:

  1. Publiceer je Lovable project — Zorg dat de site live staat op een .lovable.app URL
  2. Noteer je design keuzes — Kleuren, fonts en border-radius die je wilt behouden
  3. 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?

OnderdeelGeïmporteerdOpmerkingen
Pagina-structuurRoutes worden pagina's
Tekst-contentHeadings, paragraphs, lijsten
AfbeeldingenGekopieerd naar OptimoCMS Storage
Kleuren/fontsOmgezet naar design tokens
FormulierenGedeeltelijkBasis-velden worden overgenomen
AnimatiesMoet handmatig worden nagebouwd
Custom codeJavaScript/React niet importeerbaar

Tips voor een soepele migratie

  1. Maak een screenshot van je Lovable site vóór de import, als referentie
  2. Test op sandbox eerst — gebruik een sandbox API key om de import te testen
  3. Controleer responsive — Check de geïmporteerde pagina's op mobiel
  4. SEO bewaren — Stel redirects in als je van domein wisselt
  5. Stap voor stap — Importeer eerst, controleer, pas aan, en publiceer dan pas

Volgende stappen

On this page