Use Cases / Portfolio & Agency Sites
Portfolio & Agency Sites.
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.
Key capabilities
- 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 roles so 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 "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 "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 "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.
Terminal