CMS-krønike·marts 2026·5 minutter at læse

CMS Chronicle #08: Multi-Site Admin Én admin, mange sites

En enkelt cms-admin-instans håndterer nu flere sites på tværs af flere organisationer. Supabase-inspireret Sites Dashboard, organisationsskifter, site-specifikke indstillinger — medier, AI-konfiguration, agenter, indstillinger. Plus den omstrukturering af indstillinger, der gjorde det muligt.

Problemet

Indtil i dag har hvert site brugt sin egen cms-admin-instans. Vil du administrere to sites? Så skal du køre to Next.js-servere på to porte. Tre sites? Tre servere. Det fungerede, men det skalerede ikke — og det var ikke, hvordan platforme som Supabase, Vercel eller Fly.io fungerer.

Målet: én admin på localhost:3010, der håndterer N sites med runtime-skift mellem dem.


Site-register

Grundlaget er en registry.json-fil, der gemmes i adminens eget datamappe — adskilt fra ethvert site. Den definerer organisationer og deres sites:

{
  "orgs": [
    {
      "id": "webhouse",
      "name": "WebHouse",
      "sites": [
        {
          "id": "webhouse-site",
          "name": "WebHouse Site",
          "adapter": "filesystem",
          "configPath": "/path/to/cms.config.ts",
          "contentDir": "/path/to/content",
          "uploadDir": "/path/to/uploads"
        },
        {
          "id": "landing",
          "name": "Landing Page",
          "adapter": "filesystem"
        }
      ]
    }
  ]
}

Hvert site har sin egen konfiguration, indholdsmappe, uploadmappe og forhåndsvisnings-URL. Registret understøtter både filsystem- og GitHub-lagringsadaptere — så et sites indhold kan leve i et Git-repo i stedet for på disk.

Bagudkompatibilitet

Den kritiske begrænsning: eksisterende single-site-opstillinger skal fortsætte med at fungere uden ændringer.

Når der ikke findes nogen registry.json, læser admin CMS_CONFIG_PATH fra miljøet — præcis som før. Ingen skifter, ingen organisationsdropdown, ingen Sites Dashboard. Multi-site-laget er fuldstændig valgfrit.

CMS_CONFIG_PATH sat + intet register → single-site-tilstand (som før)
CMS_CONFIG_PATH sat + register eksisterer → multi-site-tilstand

Refaktoreringen

Dette var den største refaktorering siden projektet startede. 14 biblioteksfiler og 6 API-ruter brugte alle process.env.CMS_CONFIG_PATH til at udlede en projektmappe og finde _data/-mappen:

  • auth.ts — brugeropbevaring
  • brand-voice.ts — brandpersonlighed
  • cockpit.ts — AI-brugssporing
  • agents.ts — agentkonfigurationer
  • ai-config.ts — leverandørnøgler
  • mcp-servers.ts — MCP-forbindelser
  • curation.ts — kurateringskø
  • revisions.ts — dokumenthistorik
  • Plus seks mere.

Alle blev refaktorede til at bruge en ny getActiveSitePaths()-hjælper, der løser stier fra det aktive sites registerindgang — eller falder tilbage til miljøvariablen i single-site-tilstand.

Resultatet: Når du skifter site i dashboardet, viser mediebiblioteket de rigtige filer, AI-konfigurationen viser det rigtige sites API-nøgler, agenter tilhører det site, og forhåndsvisningen åbner det rigtige frontend.

Sites Dashboard

Inspireret af Supabase's Projekter-visning. Et kortnet, der viser alle sites i den aktive organisation:

  • Sitenavn, adaptertype (Lokal / GitHub), forhåndsvisnings-URL
  • Live-statistik: sidesantal (dokumenter med URL'er) og samlingsantal
  • Statusmærker: Aktiv, Lokal/GitHub
  • Flere menu: Kopier site-ID, gå til siteindstillinger
  • Klik på et kort for at gå ind i det sites arbejdsområde

Organisationsskifter

En dropdown i topmenuen, til venstre for brugeravataren. Samme mønster som vores app codepromptmaker — Building2-ikon, chevron, flueben på aktiv organisation. Skift organisation, og Sites Dashboard opdateres til at vise den organisations sites.

Omstrukturering af indstillinger

Multi-site tvang os til at adskille, hvad der tilhører site kontra bruger:

Siteindstillinger (i sidebaren) — ting, der adskiller sig pr. site:

  • Generelt: forhåndsvisnings-URL, papirkurvsbeholdning, kurateringsbeholdning, udviklerindstillinger
  • AI: leverandørens API-nøgler, modelvalg
  • Brand Voice: sites personlighed og tone
  • MCP: forbindelser til eksterne servere
  • Skema: samlingsdefinitioner
  • Team: medlemmer, roller, adgang (RBAC)

Brugerindstillinger (i brugermenu) — ting, der følger brugeren:

  • Generelt: navn, email, UI-zoom
  • Sikkerhed: adgangskodeændring, 2FA (autentifikator-app)
  • Adgangstokens: personlige API-tokens

Dette er ikke kun kosmetisk. Når du skifter site, skifter siteindstillingerne. Brugerindstillingerne forbliver de samme. Det er hele pointen.


Hvad vi validerede

To sites, der kører side om side:

  1. WebHouse Site — 10+ samlinger, localhost:3009, fuldt produktionsindhold
  2. Landing Page — 1 samling med blokbaserede sektioner, localhost:3010

Skift mellem dem: Mediebiblioteket viser de rigtige filer, forhåndsvisningen åbner det rigtige frontend, AI-agenter tilhører det rigtige site, indstillingerne er uafhængige. Cookien cms-active-site vedvarer på tværs af logud/logind.

Hvad kommer næste

  • GitHub-lagringsadapter som det tredje testsite (indhold lever i et repo)
  • Implementering af Team/RBAC i siteindstillinger
  • "Nyt site"-oprettelsesflow fra dashboardet
  • Landing page bygge-pipeline — gengivelse af blokke til statisk HTML fra CMS-indhold