För utvecklare

Låt kunden redigera texterna på en Next.js-sajt – utan att ge dem koden

Flytta de texter och bilder kunden vill ändra ut ur koden och in i ett CMS med strukturerade fält, och låt CMS:et trigga en revalidering av sajten när kunden sparar. Layouten och komponenterna stannar i repot, innehållet hämtas via API.

Vilket CMS som passar beror på var du vill att innehållet ska bo, hur mycket kunden ska kunna ändra och vad det får kosta. Nedan jämför vi alternativen ärligt och visar hur cachningen fungerar med App Router.

Uppdaterad 6 min läsning

Kort svar

  • Bestäm först exakt vilka fält kunden ska kunna ändra: rubriker, brödtext, bilder, priser, nyheter. Resten stannar i koden.
  • Välj typ: headless SaaS (Sanity, Storyblok), self-hosted i samma app (Payload), git-baserat (TinaCMS, Decap) eller ett enkelt CMS för strukturerade fält.
  • Hämta innehållet med fetch och en cache-tagg, och låt CMS:ets webhook anropa en route som kör revalidateTag.
  • Ge kunden strukturerade fält med validering, inte fri HTML, så kan layouten inte gå sönder.

Problemet: varje textändring blir ett ärende

En Next.js-sajt byggs ofta snabbast med texterna direkt i JSX. Det fungerar fram till lansering. Sedan vill frisören byta öppettider, snickaren lägga till en referens och caféet uppdatera lunchmenyn, och varje ändring blir ett mejl till dig.

För kunden betyder det väntetid och ofta en faktura för fem minuters arbete (mer om det i vad en textändring kostar). För dig betyder det avbrott i annat arbete. Lösningen är inte att ge kunden tillgång till repot, utan att separera innehåll från kod.

Alternativen jämförda

Gratisnivåerna nedan gäller enligt respektive leverantörs prissida i oktober 2026. Priser ändras, så kontrollera innan du lovar kunden något.

CMS-alternativ för en liten Next.js-sajt (oktober 2026)
AlternativTypVar innehållet borVad kunden serGratisnivåPassar när
SanityHeadless SaaSSanitys molndatabasSanity Studio, kan bäddas in som route i din appFree: 0 kr, 20 användare, 10 000 dokumentDu vill ha flexibla scheman och visuell redigering
StoryblokHeadless SaaSStorybloks molnVisual Editor med sajten i en iframeStarter: 0 kr, 1 användare (max 2)Kunden vill klicka direkt i sidan
PayloadSelf-hosted, öppen källkodDin egen databas (MongoDB, Postgres eller SQLite)Adminpanel i samma Next.js-appMjukvaran är gratis, du betalar drift och databasDu vill äga allt och klarar driften
TinaCMSGit-baseratMarkdown/JSON i repotRedigering med förhandsvisningTinaCloud Free: 2 användare, eller self-hostedInnehållet ska versioneras i git
Decap CMSGit-baserat, öppen källkodFiler i repot (GitHub, GitLab, Bitbucket)Admin-app i webbläsarenGratis (MIT), kräver git-inloggningEnkel blogg eller statisk sajt
JSON-filer + egen adminEget byggeDär du väljerDet du byggerGratis, men din tid kostarMycket små behov, eller du säljer det som tjänst
sitecmsStrukturerade fält, SaaSsitecmsFormulär per sida, nyheter, tjänster, SEOGratis att börjaNext.js App Router och kunden ska ändra text, bild och priser

Vad tabellen inte säger

  • Sanity kan köras som en route i appen (app/studio/[[...tool]]/page.tsx) och har en egen guide för visuell redigering med App Router. Betalnivån Growth kostar 15 USD per användare och månad enligt Sanitys prissida, oktober 2026.
  • Storyblok passar kunder som tänker visuellt. Starter beskrivs som en plan för test och personliga projekt, och nästa nivå (Growth) kostar 99 USD i månaden enligt Storybloks prissida, oktober 2026.
  • Contentful har dokumenterat stöd för live preview i App Router. Jämför gratisplanens gränser och nästa prisnivå på deras prissida innan du väljer det för en liten kund.
  • Payload installeras i /app med en egen route group och kräver vissa Next.js-versioner enligt installationsguiden. Du ansvarar själv för backup och uppdateringar.
  • TinaCMS har en guide för App Router, där sidan delas i en serverrenderad del och en klientkomponent för redigering. Decap (tidigare Netlify CMS) har en Next.js-guide som bygger på Pages Router och statisk export.
  • sitecms är en ny produkt, fungerar bara med Next.js App Router och ger strukturerade fält snarare än en fri sidbyggare. Vill kunden bygga nya sidlayouter själv är det fel verktyg.

Så syns ändringen direkt: cache-taggar och revalidateTag

Med App Router renderas sidorna oftast statiskt vid build. Hämtar du CMS-innehållet med fetch och en tagg kan du tömma just det innehållet när kunden sparar, utan att bygga om sajten.

lib/cms.tsts
export async function getPage(slug: string) {
  const res = await fetch(`${process.env.CMS_URL}/pages/${slug}`, {
    cache: "force-cache",
    next: { tags: ["cms"] },
  });
  if (!res.ok) throw new Error(`CMS svarade ${res.status}`);
  return res.json();
}
app/api/revalidate/route.tsts
import { revalidateTag } from "next/cache";

export async function POST(request: Request) {
  const body = await request.json().catch(() => null);
  if (body?.secret !== process.env.CMS_REVALIDATE_SECRET) {
    return Response.json({ revalidated: false }, { status: 401 });
  }
  // Webhook från CMS:et: nästa besökare får det nya innehållet.
  revalidateTag("cms", { expire: 0 });
  return Response.json({ revalidated: true });
}

Peka CMS:ets webhook mot /api/revalidate och skicka hemligheten i body. Enligt Next.js-dokumentationen, oktober 2026, tar revalidateTag ett andra argument: "max" visar gammalt innehåll medan nytt hämtas i bakgrunden, medan { expire: 0 } gör att nästa anrop väntar på färskt innehåll. Den äldre formen med bara taggen är markerad som utfasad. Kör du Next.js 15 tar funktionen bara taggen: skriv då revalidateTag("cms").

Exempel: koppla sajten med sitecms-next

Så här ser samma mönster ut med sitecms, som bygger på just cache-taggar. Installera paketet och lägg in miljövariablerna från panelen.

bash
npm install sitecms-next

Revalidate-routen är en rad. När kunden sparar töms cachetaggen sitecms.

app/api/sitecms/revalidate/route.tsts
export { POST } from "sitecms-next/revalidate";

Deklarera de fält kunden får redigera:

sitecms.config.tsts
import { defineConfig } from "sitecms-next";

export default defineConfig({
  pages: [
    {
      slug: "home",
      title: "Startsida",
      blocks: [
        { key: "hero.title", label: "Rubrik", help: "Max 60 tecken", default: "Välkommen" },
        { key: "hero.image", type: "image", label: "Hero-bild" },
        { key: "intro.body", type: "richtext", label: "Ingress" },
      ],
    },
  ],
});

Synka strukturen före varje build. Kundens innehåll skrivs aldrig över, nya fält får sitt default-värde.

package.jsonjson
{ "scripts": { "prebuild": "sitecms-next sync" } }

Läs innehållet i en serverkomponent:

app/page.tsxtsx
import { block, getContent, image, text } from "sitecms-next";

export default async function Home() {
  const content = await getContent();
  const hero = image(content, "home", "hero.image");
  return (
    <main>
      <h1>{text(content, "home", "hero.title", "Välkommen")}</h1>
      {hero ? <img src={hero.src} alt={hero.alt} /> : null}
      <div dangerouslySetInnerHTML={{ __html: block(content, "home", "intro.body").html }} />
    </main>
  );
}

Sedan bjuder du in kunden som redaktör via e-post. Hela uppsättningen, med getPosts() för nyheter och seo() för metadata, finns i dokumentationen.

Vad du ska tänka på innan kunden får inloggningen

  • Strukturerade fält, inte fri HTML. En rubrik är ett textfält med hjälptext och maxlängd, en bild är ett bildfält. Då kan kunden inte råka förstöra layouten.
  • Validering. Obligatoriska fält, längdgränser och rimliga standardvärden gör att en tom eller för lång text inte syns på sajten.
  • Förhandsvisning. Kunder som ändrar mycket vill se resultatet innan det publiceras. Sanity, Storyblok och TinaCMS har visuell redigering; andra visar ändringen först på sajten.
  • Roller. Kunden ska vara redaktör, inte admin. Strukturen och API-nycklarna ägs av den som underhåller sajten.
  • Alt-text. Gör alt-text till ett eget fält bredvid varje bild och förklara varför det spelar roll.
  • Ångra. Kontrollera hur man återställer en ändring: versionshistorik, git-historik eller ångra-funktion.

När allt fungerar: gå igenom överlämningschecklistan och visa kunden hur det går till. Har kunden redan en sajt byggd i Next.js och vill förstå sina alternativ finns en guide skriven för dem.

Vanliga frågor

Vilket CMS passar en liten Next.js-sajt?

Ska kunden bara ändra texter, bilder och priser räcker ett CMS med strukturerade fält. Vill kunden klicka direkt i sidan är Storyblok eller Sanity med visuell redigering starka val. Vill du äga allt själv passar Payload, och vill du ha innehållet i git passar TinaCMS.

Måste jag bygga om sajten för att lägga till ett CMS?

Nej. Komponenterna och layouten blir kvar, du byter bara hårdkodade strängar mot värden som hämtas från CMS:et. Börja med de sidor kunden faktiskt ändrar och låt resten vara.

Hur får jag ändringar att synas direkt med App Router?

Hämta innehållet med fetch och en cache-tagg, och skapa en route handler som kör revalidateTag när CMS:ets webhook anropar den. Då töms bara det taggade innehållet och sajten behöver inte byggas om.

Vad kostar ett headless CMS för en liten kund?

Flera har gratisnivåer som räcker för en liten sajt, till exempel Sanitys Free-plan och Storybloks Starter enligt deras prissidor i oktober 2026. Begränsningarna gäller ofta antal användare, så kontrollera dem innan du väljer.

Källor