Use Cases / Portfolio & Agency

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.

The problem

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.

Example

Portfolio schema: collections and singles

Projects collection

collections/projects.ts
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

collections/testimonials.ts
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)

singles/about.ts
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