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.
Bildkredit: Bild av @altumcode frÄn Unsplash
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.
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 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.
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.
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.
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.
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.
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.
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.
Genom att bygga upp bloggplattformen lÀrde vi oss vÀrdefulla saker om Payload CMS:s ekosystem:
payload-types.ts
fÄngade upp fel tidigt, vilket sparade oss felsökningstid jÀmfört med JSON-baserade CMS-plattformar.VÀlkommen till Tech Exploration, dÀr Ketryon testar innovativa verktyg för att driva moderna lösningar. I den hÀr utgÄvan dyker vi in i att bygga headless e-handelsbutiker med Shopify Hydrogen.
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 Model Context Protocol (MCP).