Build it in code. Hand it off to your client.
Define projects, services, and testimonials as collections and About/Contact as singles. Your client gets a clean admin panel to update content. You keep full control of the data model in your repository.
Collections + Singles
Projects, services, and testimonials as collections. About page and contact info as singles, one document, always there.
Media Library
Upload project screenshots, team photos, and client logos. Sharp processing for automatic optimization and responsive sizes.
Client Access
Set up editor rolesso clients manage content without touching schema, settings, or anything they shouldn't see.
Code-first Schema
Define the collection fields in TypeScript. The schema is version-controlled alongside your frontend, no surprises after a client edit.
Client sites need an admin. Building one from scratch is a project in itself.
Your client needs to update their portfolio, add testimonials, and swap out service descriptions without calling you. Building a custom admin is overkill. A hosted CMS adds another monthly subscription and a separate deployment to babysit.
Nextly gives you a full admin panel as part of the Next.js project you're already deploying. No extra service, no extra cost.
Portfolio schema: collections and singles
Projects collection
import {
defineCollection, text, richText,
upload, relationship, select,
} from"@revnixhq/nextly/config";
export default defineCollection({
slug:"projects",
fields: [
text({ name:"title", required: true }),
text({ name:"client" }),
text({ name:"slug", unique: true }),
richText({ name:"description" }),
upload({ name:"thumbnail", relationTo:"media" }),
upload({ name:"gallery", relationTo:"media", hasMany: true }),
relationship({
name:"services",
relationTo:"services",
hasMany: true,
}),
select({
name:"category",
options: [
{ label:"Web", value:"web" },
{ label:"Mobile", value:"mobile" },
{ label:"Branding", value:"branding" },
],
}),
],
});Testimonials collection
import {
defineCollection, text, upload, number,
} from"@revnixhq/nextly/config";
export default defineCollection({
slug:"testimonials",
fields: [
text({ name:"quote", required: true }),
text({ name:"author", required: true }),
text({ name:"role" }),
text({ name:"company" }),
upload({ name:"avatar", relationTo:"media" }),
number({ name:"rating", min: 1, max: 5 }),
],
});About page (single)
import {
defineSingle, text, richText, upload,
} from"@revnixhq/nextly/config";
export default defineSingle({
slug:"about",
fields: [
text({ name:"headline", required: true }),
richText({ name:"bio" }),
upload({ name:"photo", relationTo:"media" }),
text({ name:"email" }),
],
});Start building with Nextly
Free, open source, and yours to own. No sign-up required.
npx create-nextly-app@latest