Tillbaks till resurser

Teknisk utforskning: Bygga en bloggplattform med Payload CMS

VÀlkommen till Tech Exploration, dÀr Ketryon testar banbrytande verktyg för att driva moderna lösningar. I den hÀr utgÄvan dyker vi in i att bygga appar med Payload CMS.

Teknisk utforskning: Bygga en bloggplattform med Payload CMS

Bildkredit: Bild av @altumcode frÄn Unsplash

Payload CMSNext.jsTypeScriptContent Management
Av Kenny TranPublicerades den 4/5/2025Uppdaterades senast den 4/5/2025

Inledning

PÄ Ketryon Àr vi passionerade för verktyg som ger företag skrÀddarsydda, skalbara lösningar. DÀrför bestÀmde vi oss för att utforska Payload CMS, ett headless CMS och applikationsramverk som blandar utvecklarkontroll med anvÀndarvÀnlig innehÄllshantering. Till skillnad frÄn rigida plattformar som WordPress lÄter Payload oss definiera innehÄll i kod och integreras sömlöst med Next.js för webbplatser, appar och verktyg. Vi byggde en minimal bloggplattform för att testa dess ekosystem och visa dess potential för startups och svenska företag som söker flexibla, GDPR-kompatibla innehÄllslösningar.

Vad Àr Payload CMS?

Payload CMS Àr ett headless CMS och applikationsramverk med öppen kÀllkod, TypeScript-first, byggt med Node.js, React och MongoDB eller Postgres. Till skillnad frÄn WordPress, som förlitar sig pÄ förbyggda mallar, lÄter Payload utvecklare definiera innehÄllsscheman i kod, skapa REST- och GraphQL API:er och ett anpassningsbart admin-grÀnssnitt. Det integreras nativt med Next.js och körs i samma projekt för en enhetlig stack. TÀnk pÄ Payload som en backend-byggare: det Àr som att sÀtta ihop en anpassad databas och API med legoklossar, skrÀddarsydda för din apps behov, allt inom ett JavaScript/TypeScript-arbetsflöde. Dess MIT-licens hÄller det gratis för alla projekt.

Viktiga egenskaper inkluderar:

  • Payload Config: En TypeScript-fil för att definiera innehĂ„ll, autentisering och anvĂ€ndargrĂ€nssnitt.
  • Collections and Globals: Samlingar lagrar flera objekt (t.ex. blogginlĂ€gg), medan globaler lagrar enstaka instĂ€llningar (t.ex. webbplatsens titel).
  • APIs: Autogenererade REST-, GraphQL- och lokala API:er för snabb dataĂ„tkomst.
  • Admin UI: En React-baserad dashboard för redaktörer, anpassningsbar med kod.
  • Authentication: Inbyggd inloggning och roller för anvĂ€ndare, sĂ€krade med JWT.
  • Database Support: Fungerar med MongoDB, Postgres m.fl. via adaptrar.

Varför det Àr relevant

Payload CMS förenar flexibilitet för utvecklare och anvÀndbarhet för innehÄllsredaktörer, till skillnad frÄn traditionella CMS-plattformar som begrÀnsar anpassningsmöjligheterna. Dess kod-först-strategi sparar tid och kostnader för företag och utvecklare.

  • For Företag: Payloads förbyggda API:er och autentisering minskar tiden för kodning av backend, vilket minskar kostnaderna för en blogg eller app frĂ„n veckor till dagar. För svenska företag sĂ€kerstĂ€ller den rollbaserade Ă„tkomsten och schemakontrollen GDPR-kompatibel datahantering, perfekt för e-handel eller SaaS. Företag som Microsoft och ASICS anvĂ€nder Payload för skalbara innehĂ„llslösningar.
  • For Utvecklare: Payloads TypeScript-first-design och Next.js-integration passar vĂ„r JavaScript-expertis. Dess lokala API hĂ€mtar data direkt inom Next.js, vilket snabbar upp sidladdningar jĂ€mfört med externa API-anrop. X-inlĂ€gg kallar det ”en utvecklares dröm” för sitt rena dataflöde.
  • Branschtrender: Payloads 3.0-release 2024 ökade dess popularitet och tusentals projekt anvĂ€nde det för webbplatser och verktyg. Dess Next.js-fokus och vĂ€xande community gör det till ett förstahandsval för moderna appar.

VÄr provkörning

För att dyka in i Payload CMS:s ekosystem byggde vi en minimal bloggplattform med hjÀlp av Payload, Next.js och TypeScript. VÄrt mÄl var att skapa en webbapp dÀr anvÀndarna skapar inlÀgg, hanterar kategorier och fÄr tillgÄng till innehÄll via ett publikt API, och vi utforskade viktiga aspekter: schemadefinition, anpassning av administratörsgrÀnssnittet, API-integration, autentisering och distribution. Plattformen erbjuder en flexibel lösning för innehÄllsdrivna företag som bloggar eller startup-webbplatser.

Projekt UppsÀttning

Vi initierade ett Next.js-projekt med Payload

npx create-next-app@latest blog-platform --typescript
cd blog-platform
npm i payload @payloadcms/next @payloadcms/richtext-lexical @payloadcms/db-mongodb mongoose

AnmÀrkning: create-next-app inkluderar Next.js- och React-beroenden. Vi lade till Payload, dess Next.js-integration, Lexical rich-text editor och MongoDB-adapter. Vi kopierade Payloads mallfiler (payload.config.ts, payload-types.ts) till /src/app/(payload) och anslöt till en MongoDB Atlas-instans. I payload.config.ts konfigureras Payload:

import { buildConfig } from "payload";
import { mongooseAdapter } from "@payloadcms/db-mongodb";
import { lexicalEditor } from "@payloadcms/richtext-lexical";
import { Posts } from "./collections/Posts";
import { Categories } from "./collections/Categories";
import { Users } from "./collections/Users";

export default buildConfig({
  collections: [Posts, Categories, Users],
  editor: lexicalEditor(),
  db: mongooseAdapter({ url: process.env.MONGODB_URI }),
  typescript: { outputFile: "./payload-types.ts" },
});

Att köra npm run dev startade Next.js och Payloads admin UI pÄ /admin, sÄ att vi kan testa innehÄllsskapande.

Schema Definition

Scheman definierar appens datastruktur, som en plan för innehÄll. Vi skapade tvÄ samlingar (Posts, Categories) och en Users-samling för autentisering. Samlingen Posts (collections/Posts.ts) definierade fÀlt för blogginlÀgg:

import { CollectionConfig } from "payload";

export const Posts: CollectionConfig = {
  slug: "posts",
  admin: { defaultColumns: ["title", "category", "createdAt"] },
  fields: [
    { name: "title", type: "text", required: true },
    {
      name: "content",
      type: "richText",
      required: true,
      editor: lexicalEditor(),
    },
    {
      name: "category",
      type: "relationship",
      relationTo: "categories",
      required: true,
    },
    { name: "createdAt", type: "date", admin: { readOnly: true } },
  ],
};

Samlingen Categories var enklare:

import { CollectionConfig } from "payload";

export const Categories: CollectionConfig = {
  slug: "categories",
  fields: [{ name: "name", type: "text", required: true }],
};

Payload genererade TypeScript-grÀnssnitt i payload-types.ts, vilket sÀkerstÀller typsÀkra förfrÄgningar och rendering.

Anpassning av Admin UI

Admin UI lÄter redaktörer hantera innehÄll utan kodning. Vi anpassade det för att förbÀttra upplevelsen av att skapa inlÀgg genom att lÀgga till ett fÀlt för förhandsgranskning av titeln (collections/Posts.ts):

import { Field } from "payload";

const TitlePreview: Field = {
  name: "titlePreview",
  type: "ui",
  admin: {
    components: {
      Field: ({ value }: { value?: string }) => (
        <div style={{ fontSize: "1.2em", color: "#333" }}>
          Preview: {value || "No title entered"}
        </div>
      ),
    },
  },
};

export const Posts: CollectionConfig = {
  slug: "posts",
  admin: { defaultColumns: ["title", "category", "createdAt"] },
  fields: [
    { name: "title", type: "text", required: true },
    TitlePreview,
    {
      name: "content",
      type: "richText",
      required: true,
      editor: lexicalEditor(),
    },
    {
      name: "category",
      type: "relationship",
      relationTo: "categories",
      required: true,
    },
    { name: "createdAt", type: "date", admin: { readOnly: true } },
  ],
};

Den lexikala redigeraren gav möjlighet till redigering av rik text och lagrade innehÄllet som JSON för flexibilitet. VÄrt anpassade fÀlt förbÀttrade redigerarens arbetsflöde med en förhandsgranskning i realtid.

API Integration

Payloads lokala API hÀmtar data inom Next.js, perfekt för snabb rendering pÄ serversidan. I app/page.tsx visade vi inlÀgg:

import { getPayload } from "@payloadcms/next";
import { Post } from "../../payload-types";
import { renderRichText } from "@payloadcms/richtext-lexical";

export default async function Home() {
  const payload = await getPayload();
  const { docs: posts } = await payload.find({
    collection: "posts",
    sort: "-createdAt",
    depth: 1, // Populate category
  });

  return (
    <div style={{ padding: "20px" }}>
      <h1>Blog Platform</h1>
      {posts.map((post: Post) => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{(post.category as { name: string })?.name}</p>
          <div>{renderRichText(post.content)}</div>
        </article>
      ))}
    </div>
  );
}

Vi anvÀnde @payloadcms/richtext-lexical för att rendera JSON-innehÄllet frÄn den lexikala redigeraren. Alternativet djup: 1 fyllde i category.name. Vi testade ocksÄ REST API (/api/posts) för extern Ätkomst, vilket bekrÀftade dess mÄngsidighet.

Autentisering

Vi har aktiverat anvÀndarautentisering för rollerna admin och editor (collections/Users.ts):

import { CollectionConfig } from "payload";

export const Users: CollectionConfig = {
  slug: "users",
  auth: true,
  fields: [
    { name: "name", type: "text", required: true },
    {
      name: "role",
      type: "select",
      options: ["admin", "editor"],
      required: true,
    },
  ],
};

Payloads JWT-baserade inloggning och rollbaserade Ätkomst fungerade direkt frÄn start. Vi anpassade inloggningssidan (app/(payload)/admin/page.tsx):

import { Login } from "@payloadcms/next";

export default function AdminLogin() {
  return (
    <div style={{ padding: "40px", textAlign: "center" }}>
      <h1>Ketryon Blog Admin</h1>
      <Login />
    </div>
  );
}

Detta sÀkrade administratörsgrÀnssnittet och begrÀnsade redaktörerna till inlÀgg och kategorier.

LĂ€rdomar

Genom att bygga upp bloggplattformen lÀrde vi oss vÀrdefulla saker om Payload CMS:s ekosystem:

  • Schema Definition: Att definiera samlingar i TypeScript var intuitivt, och payload-types.ts fĂ„ngade upp fel tidigt, vilket sparade oss felsökningstid jĂ€mfört med JSON-baserade CMS-plattformar.
  • Admin UI: Att anpassa anvĂ€ndargrĂ€nssnittet med React-komponenter, som vĂ„r förhandsgranskning av titeln, var enkelt och ökade redaktörens produktivitet, men genom att planera anpassade fĂ€lt i förvĂ€g undveks omarbetningar.
  • APIs: Det lokala API:ets hastighet förĂ€ndrade vĂ„r Next.js-rendering och minskade sidladdningstiderna jĂ€mfört med externa REST-anrop. Test av REST- och GraphQL-API:er visade deras flexibilitet för appar som vĂ€nder sig till allmĂ€nheten.
  • Authentication: Payloads JWT-autentisering var plug-and-play och möjliggjorde sĂ€ker administratörsĂ„tkomst pĂ„ bara nĂ„gra timmar, med rollbaserade kontroller i linje med GDPR-kraven för svenska kunder.
  • Deployment: Vercels integration förenklade hostingen och OTA-uppdateringar gör att vi kan justera admingrĂ€nssnittet utan driftstopp, vilket Ă€r perfekt för snabb iteration.

Referenser

  1. https://payloadcms.com/docs/getting-started/what-is-payload
  2. https://payloadcms.com/docs/access-control/overview
  3. https://payloadcms.com/docs/local-api/overview