Skip to content
Docs
Sign inGet Pro

Editing the content — Findit Next.js

All the words and images of the site live in src/content/. You edit plain TypeScript files — quotes around text, commas between items — and the site updates while npm run dev is running. No CMS is needed. (If you would rather manage content in Sanity, Payload, Strapi or Directus, see Using a headless CMS.)

src/content/
site.ts name, description, domain, navigation, contact details, footer, social links
pages/home.ts the copy of the home page
pages/about.ts …and of every other page
sections.ts copy of sections that appear on several pages (benefits, process, FAQ, facts, …)
collections/*.ts properties, agents, locations, categories, testimonials, posts, legal, team
routes.ts the URL of every page
types.ts the fields each kind of item has

Not sure which file holds a piece of text? The page maps label every section of every page with its file.

src/content/site.ts holds what appears on every page:

Field Shown where
site.name Logo alt text, browser title suffix, share cards
site.title Browser title of the home page
site.description Search results and share cards, for pages without their own description
site.url Set this to your domain before publishing. Canonical links, share links, sitemap.xml and robots.txt are built from it
navigation The menu in the header
headerActions The two buttons in the header (the first one is filled)
contact Address, phone numbers, email and opening hours — used on the Contact page and in the footer
socials The social links in the footer
footer The call-to-action above the footer, the two link columns, the newsletter texts and the copyright line ({year} becomes the current year)

Links use routes (routes.about, routes.post("my-slug")) so a URL is written once and stays in sync.

One file per page in src/content/pages/. Each exports an object with the sections of that page and a meta entry:

export const about = {
meta: {
title: "About us", // browser tab: "About us | Findit"
description: "Findit connects buyers…", // search results and share cards (80–160 characters)
},
hero: { … },
history: { … },
};

Change the text between the quotes, keeping the field names — the sections read them by name. Apostrophes are safe inside double quotes, and the demo uses the typographic ’. A double quote inside a double-quoted string needs a backslash before it.

The Properties page’s meta also holds the titles and descriptions of the filter pages. {name} in them is replaced by the location or category name: "Properties in {name}".

src/content/collections/ holds the lists the site builds pages from:

File What it feeds
properties.ts The Properties list, one page per property, the filters, the home page (Featured, Latest) and each agent’s list
agents.ts The Agents page, one page per agent, the agent card on every property
locations.ts The location filter pages, the cities on the home page, the location of a property
categories.ts The category filter pages and the tabs of “Latest properties”
posts.ts The Blog, one page per post, “More Blog”
testimonials.ts The two tickers (desktop) and the carousel (phone and tablet)
team.ts The team grid on About
legal.ts Terms of Service and Privacy Policy, one page each (/legal/<slug>)

The order of the items in the file is the order on the site. The home page shows the first five properties that have featured: true, the first six properties of a tab in “Latest properties”, and the three first posts. A property page ends with up to two more properties in the same location and four in the same category; a post ends with up to three more posts of the same category.

Copy an existing entry, paste it below, and change the values:

{
slug: "harbor-view-loft", // the URL: /property/harbor-view-loft
title: "Harbor View Loft",
propertyId: "55L120", // shown in the tour form
for: "sell", // "sell" or "rent"
featured: false, // true: may appear in the home page's Featured section
category: "apartments", // a slug from categories.ts
agent: "steve-parker", // a slug from agents.ts
location: "brooklyn", // a slug from locations.ts
address: "12 Pier Street, Brooklyn, NY 11201",
price: 640000, // dollars, shown as $640,000
duration: "/Month", // shown after the price of properties for rent only
image: "/images/property-harbor-view-loft.jpg", // a file in public/images
gallery: [ // four more photos
"/images/property-harbor-view-loft-2.jpg",
"/images/property-harbor-view-loft-3.jpg",
"/images/property-harbor-view-loft-4.jpg",
"/images/property-harbor-view-loft-5.jpg",
],
video: "https://www.youtube.com/watch?v=…", // optional YouTube link
description: [{ type: "paragraph", text: "**Harbor View Loft** is …" }],
features: [{ type: "paragraph", text: "…" }],
details: {
size: 120, bedrooms: 2, bathrooms: 2, floor: "3", additionalSpace: "Balcony", furnishing: "Semi furnished",
ceilingHeight: 3, constructionYear: "2015-01-01", renovation: "2023-01-01",
},
utility: {
heating: "Central", airCondition: "Yes", fireplace: "-", elevator: "Yes", ventilation: "Yes",
intercom: "Yes", windowType: "Aluminum frame", cableTv: "Yes", wifi: "Yes",
},
}

slug must be unique and URL-safe (lower case, words joined by -). The page, its card everywhere, its place in the filters and its entry in sitemap.xml appear by themselves — there is nothing else to register. Cards show the size under the name “Sqft”; the number is whatever you enter (the demo uses square metres, and the property page says m2).

A location or category that no property uses is not listed: the home page shows only the cities that have properties, the filter card only the chips that lead somewhere. “No Location” and “Uncategory” are fallback items for properties without a real one; keep or delete them.

Adding an agent, location, category, post or team member

Section titled “Adding an agent, location, category, post or team member”
Add Fields
Agent slug, name, image (portrait, ratio about 0.7), address, bio, phone, mobile, whatsapp (digits, no +), email
Location slug, name, image (used by the city cards on the home page)
Category slug, name
Post slug, title, category (any word; posts with the same one are shown as “More” under each other), date ("2026-05-16"), author, image, excerpt (the card text: the post’s first sentence), body
Team member name, role, bio, photo
Testimonial slug, name, photo, rating (1–5 stars), title, quote
Legal text slug, title, description (search results), updated ("2023-11-16"), body

An agent’s page lists every property whose agent is that agent’s slug, so a new agent needs no list of their own.

Delete the entry. Items refer to each other by slug: a property names its agent, location and category. A property page whose agent, location or category no longer exists answers “404 Not found”, and its card in the lists shows an empty agent or the raw slug. Search the project for the slug you deleted (Ctrl/Cmd + Shift + F) and update every property that still points at it before you publish.

src/content/types.ts is the reference: it lists every field, which are optional (?), and a comment for the ones that are not obvious. Your editor shows the same information while you type.

Section titled “Rich text: descriptions, posts and legal texts”

A description, a post body or a legal text is a list of blocks:

body: [
{ type: "heading", text: "1. Information we collect" },
{ type: "paragraph", text: "A paragraph with **bold text** and a [link](/contact) inside it." },
{ type: "list", items: ["**First** item", "Second item"] }, // bullets
{ type: "list", ordered: true, items: ["Step one", "Step two"] }, // numbers
]

Bold text is wrapped in **double stars**, links are text, and \n inside a text is a line break. Property descriptions and features use paragraphs; posts too; legal texts use headings and lists as well.

The video on the home page is hero.video in src/content/pages/home.ts: src is a file or a web address, poster the picture shown before it plays. The demo plays a clip straight from Pexels; to use your own, put an MP4 in public/videos/ and set src: "/videos/tour.mp4". Nothing is downloaded until a visitor presses play.

  1. Put the file in public/images/.
  2. Refer to it in the content as /images/<file> (the path starts at public).

Sizes and formats are handled for you: pages use next/image, which serves a scaled, modern format per device. Use photos at least as wide as they appear (property and post photos: 1400 px or more, cards: 1200 px, portraits: 800 px), in .jpg for photos and .png when you need transparency. Keep the demo’s aspect ratios (the layout crops to fit).

Two things sit outside the content because browsers and social networks ask for them by name:

File What it is
src/app/icon.svg, src/app/apple-icon.png The icon in the browser tab and on a phone’s home screen
public/opengraph-image.png The picture shown when someone shares a link (2400 × 1260; 1200 × 630 or larger)

Its description for screen readers is shareImage.alt in src/lib/meta.ts. Every page uses this image when shared, except the property, agent and post pages, which share their own image.

The search-result description of a property is the first sentence of its description, of an agent the first sentence of their bio, and of a post its excerpt — start each with a real sentence.

Interface words that never change per site — “Beds”, “Baths”, “Sqft”, form messages — live with the components in src/design-system/. Search for the phrase and you will find it. Everything a visitor reads as your words is in src/content/.

Terminal window
npm run build

A successful build means every page, link and image still resolves. See Going live for the rest of the checklist.