Skip to content
Sign inJoin waitlist

Editing the content — Ciketo 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, menu, contact details, footer, and the parts several pages share
pages/home.ts the copy of the home page
pages/about.ts …and of every other page
collections/*.ts services, lanes, posts, testimonials, clients, legal pages
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, and the sections that several pages share:

Export Shown where
site.name Logo label for screen readers, browser title suffix, share cards
site.title The browser title of the home page, and of any page without its own.
site.description Search results and share cards of the home page, and of 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 (and the phone menu)
headerAction The button on the right of the header (“Get a Quote”)
clock The language of the date under the header clock: locale: "en-GB" shows “5 October 2026”. The time is the visitor’s own, on a 24-hour clock.
contact Address, phone and e-mail (footer and Contact page), supportEmail (shown with the phone next to the services on Home), and the “Phone:” / “Email:” labels
socials The Social column of the footer
footer The tagline, the Company and Services columns, the Social and Contact column titles, the copyright line ({year} becomes the current year) and the legal links
cta The dark call to action above the footer of Home, About, Services and Blog: label, title, text, photo and two buttons
howItWorks “How It Works” on Home, Services and every service page: four steps, each with a title, description, label, info and photo
industries “Industries We Serve” on Home and About: six industries and the five photos between them
clientsIntro The label and the line before the client logos (Home, About)
facts The four figures on Home and About (“15+ Years”, …): value, unit and description
quoteForm The quote form on Home, Contact and every service page: label, title, text, photo, group titles, fields, consent line, button and messages (Forms)

The demo’s e-mails (hello@example.com, support@example.com), phone number and address are placeholders: replace all of them. The phone number is also the link of “Call Customer Service” in the call to action (cta.secondary.href: "tel:+18005550147"). The footer’s Services column is a list of links, not the collection: update it when you add, remove or rename a service.

There is one file per page in src/content/pages/. Each exports an object with the sections of that page and, for pages with a fixed URL, a meta entry:

export const about = {
meta: {
title: "About Us", // browser tab: "About Us | Ciketo"
description: "A logistics partner that moves…", // search results and share cards (80–160 characters)
},
hero: { … },
story: { … },
leader: { … },
};

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.

File Page
home.ts Home: the hero and its figures, “Why Choose Us” with its quote, the services heading and the help card beside the list, the photo band, the blog heading and the FAQ (faq.items). It has no meta: its title is in src/app/page.tsx and its description is site.description.
about.ts About: the hero, “Who we are” and the leader’s message (leader)
services.ts Services: the title and the words in each row (“Explore”, “Key Benefits”)
service.ts The words shared by every service page: the label, “Our solutions”, the “Lanes” after the service name, “Departure:” and “Arrival:”, and the photo next to the key benefits
blog.ts Blog, with the text screen readers hear while more posts load
post.ts The words shared by every post: “Date:” and “Other Posts”
contact.ts Contact: title, text, photo, the “Contact” column title and the business hours (hours.rows)
legal.ts “Last Updated:” on the legal pages
not-found.ts The 404 page

The Home hero’s figures are copy too (hero in home.ts): the “98.5% on time” pill, the booking note, the “Enterprise accounts” card (the four names under it are the first four clients) and “Lanes Open”. The lane card at its bottom right shows the first lane in lanes.ts.

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

File What it feeds
services.ts The Services page, one page per service, and the services list on Home (all of them, numbered 01, 02, … in the file’s order)
lanes.ts The lanes on each service page (the ones the service names in lanes.items) and the “New Lane” card in the Home hero (the first lane)
posts.ts The Blog (six at a time as you scroll), one page per post, Home (the first three) and “Other Posts” at the end of a post (up to three of the same category)
testimonials.ts The testimonials on Home (all of them)
clients.ts The logo ticker on Home and About (all of them) and the four names in the Home hero (the first four)
legal.ts One page per legal text: /legal/privacy-policy, /legal/terms-conditions, /legal/cookie-policy

The order of the items in the file is the order on the site. The Blog doesn’t sort posts by date either: put a new post first to show it first.

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

{
slug: "rail-freight", // the URL: /services/rail-freight
title: "Rail Freight",
summary: "Cost-efficient rail transport…", // the service lists, the top of its page, its search description
image: "/images/service-rail-freight.jpg", // the top of its page, the Home list and Services (about 2400 × 1600)
about: {
title: "Reliable Rail Across Europe.",
text: "…",
facts: [{ value: "40+", label: "Rail Terminals" }, …], // four figures in white cards
},
benefits: {
title: "Rail Freight for Every Load.",
items: [{ title: "Block Trains", description: "…" }, …], // four key benefits
},
lanes: {
title: "Connected Across the Continent.",
text: "…",
items: ["ningbo-hamburg", "singapore-rotterdam"], // slugs from lanes.ts, shown in this order
},
}

A service page shows its name and summary above its photo, then about, benefits (beside the photo set in service.ts) and its lanes. The titles of the key benefits are also the bullet list under “Key Benefits” on the Services page.

Two lists elsewhere name the services and don’t follow the collection: the footer’s Services column (footer.services.links in site.ts) and the quote form’s shipping methods (quoteForm.fields.method.options).

Adding a lane, post, testimonial, client or legal page

Section titled “Adding a lane, post, testimonial, client or legal page”
Add Fields
Lane slug, title ("Jebel Ali → Rotterdam"), departure and arrival (the ports), transit (the range on the card, "22–28 Days"), average (the Home hero card, "24 Days"), frequency ("Weekly"), description (kept from the original design; no section shows it), image (about 800 × 533). Then add its slug to the lanes.items of the services that use it.
Post slug, title, excerpt (the card text and the search description), image (about 2400 × 1600), category (any words; posts with the same one are listed under each other as “Other Posts”), date ("2026-08-26", shown as “Aug 26, 2026”), body (rich text)
Testimonial slug, title (the quote’s headline), quote, name, role, company, photo (square, about 800 × 800) and rating (out of 5: 5 shows “5.0/5” and five stars)
Client slug, name (also the logo’s text for screen readers) and logo: an SVG file in public/images/, shown 16 px tall at its own width
Legal page slug (the URL, /legal/<slug>), title, updated ("2026-09-02", shown as “Last Updated: Sep 2, 2026”) and body (rich text). Link it from footer.legal in site.ts.

A post’s search description is its excerpt, a service’s its summary and a legal page’s its first paragraph, cut at 160 characters.

Delete the entry. Its page, its card and its sitemap entry disappear on the next build. A service names its lanes by slug: when you delete a lane, take its slug out of the services too (a slug that matches no lane is skipped). Links written out in site.ts (the footer’s Services column, the legal links) stay until you remove them.

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.

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

body: [
{ type: "heading", text: "Information We Collect" }, // a heading
{ type: "heading", level: 3, text: "Information You Provide" }, // a smaller heading
{ type: "paragraph", text: "A plain paragraph." },
{ type: "paragraph", highlight: "Bold start:", text: " and the rest of the paragraph." },
{ type: "list", items: [ // bullets; ordered: true for numbers
[{ type: "paragraph", text: "First item" }],
[{ type: "paragraph", highlight: "Second:", text: " with a bold start" }],
] },
]

Each list item is itself a list of blocks, so a numbered item can hold paragraphs and a nested list. Text is plain: the bold parts are highlight, not **stars**. The demo’s posts are paragraphs only; the legal pages use headings at both levels.

  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 large as the demo’s, which the placeholders show:

Photos Demo size
Home hero (also behind the 404 page), the photo band on Home, the About photo, the call to action, service and post photos 2400 px wide
The Contact cover 2400 × 3600, portrait
“Who we are” on About (also next to the key benefits on every service page) 1200 × 1600, portrait
“Why Choose Us” on Home (the first also beside the quote form) 1200 × 773 and 600 × 400
Industries 1200 × 814 for the wide first photo, 600 px wide for the others
Lanes, steps, the help card next to the services 800 px wide
Testimonial portraits 800 × 800
James Carter (Home quote, About) and Sarah Mitchell (the help card) 600 × 600 and 200 × 200

Keep the demo’s aspect ratios, because the layout crops to fit. A photo used in two places changes in both when you replace the file; to show different photos, give one of them another path in the content.

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 service and post pages, which share their own photo.

Almost every word is content, including the form’s messages (quoteForm in site.ts). The few interface words that never change per site live in the code:

  • “Menu” (the phone menu button’s label for screen readers) and “Main” (the menu’s name) in src/design-system/, and “Phone” (the phone menu’s name) in src/components/site/Header.tsx;
  • “Clients” (the name of the logo ticker for screen readers) in src/components/sections/ClientsSection.tsx;
  • “/5” after a testimonial’s rating in src/components/sections/TestimonialsSection.tsx;
  • the date format of posts and legal pages (“Aug 26, 2026”) in src/lib/format.ts.

Search for the word and you will find it.

Terminal window
npm run build

A successful build means every content file has the fields it needs and every page still renders. It doesn’t open the images or the links written as text ("/contact"): click through the site once with npm start after big changes. See Going live for the rest of the checklist.