Skip to content
Sign inJoin waitlist

Using a headless CMS — Ciketo Next.js

Connecting a headless CMS works the same for every Framebrick Next.js template. The approach, rich text, images, keeping pages fresh, and step-by-step guides for Sanity, Payload, Strapi and Directus are in Use a headless CMS with a Next.js template. This page lists what is specific to Ciketo.

Pages read them through src/lib/content.ts: getServices / getService, getLanes / getServiceLanes, getPosts / getPost / getRelatedPosts, getTestimonials, getClients and getLegalPages / getLegalPage. Mirror src/content/types.ts in the CMS:

Collection Key fields
Service slug, title, summary, image, about (title, text, four facts: value and label), benefits (title, four items: title and description), lanes (title, text, the slugs of its lanes)
Lane slug, title, departure, arrival, transit, average, frequency, description, image
Post slug, title, excerpt, image, category, date, body (rich text)
Testimonial slug, title, quote, name, role, company, photo, rating (out of 5)
Client slug, name, logo
LegalPage slug, title, updated, body (rich text)
  • A service lists its lanes by their slug (lanes.items). Model them as references to several lanes and return the slugs in your mapping function; getServiceLanes keeps the service’s order and skips a slug it can’t find.
  • “Other Posts” under a post shows up to three posts of the same category (getRelatedPosts). The demo uses three categories (Shipping, Supply Chain, Logistics): a choice field or a reference whose name you return.
  • Keep the collection’s order in the CMS (a sort field), because the site shows items in the order it receives them, not by date. Home shows every service (numbered 01, 02, … in that order), every testimonial and the first three posts; the hero shows the first lane and the names of the first four clients; the logo ticker shows every client; the Blog shows six posts at a time.
  • A lane’s description comes from the original design; no section shows it.
  • The footer’s Services column and legal links, and the quote form’s shipping methods, are lists in src/content/site.ts, not collections.

Post bodies and the legal pages are blocks, not HTML:

{ type: "heading", text: "…", level?: 2 | 3 } // 2 by default; 3 is a smaller heading
{ type: "paragraph", text: "…", highlight?: "…" } // highlight: a bold start
{ type: "list", ordered?: true, items: [[ …blocks ], [ …blocks ]] } // each item is a list of blocks

The demo’s posts are paragraphs only; the legal pages use headings at both levels. Convert your CMS’s rich text to these blocks in your mapping function (how).

Upload images at least as large as the layout uses: 2400 px wide for service and post photos (they fill the width at the top of their page), 800 px for lane photos and 800 × 800 for testimonial portraits. Client logos are SVG files shown 16 px tall at their own width, in a plain <img>, so they load from any address. Using a CMS’s images in the site: Images.