Pages and sections — Ciketo Astro
A page is a small file that picks sections and hands them content. src/pages/blog.astro is the whole Blog page:
---import BlogListSection from "../components/sections/BlogListSection.astro";import CtaSection from "../components/sections/CtaSection.astro";import blogPage from "../content/pages/blog.json";import siteContent from "../content/site.json";import Layout from "../layouts/Layout.astro";import { getPosts } from "../lib/content";import { toPostCard } from "../lib/to-ui";
const posts = await getPosts();---
<Layout title={blogPage.meta.title} description={blogPage.meta.description}> <BlogListSection label={blogPage.label} title={blogPage.title} loading={blogPage.loading} posts={posts.map(toPostCard)} /> <CtaSection {...siteContent.cta} /></Layout>Layoutgives the page its browser title, description, canonical link, share image, header and footer.getPosts()reads the collection (see Editing the content).toPostCardturns each post into what the card shows (src/lib/to-ui.ts).- The sections render them;
CtaSectiontakes the call to action fromsrc/content/site.json.
The sections you can use
Section titled “The sections you can use”In src/components/sections/, one file per section. Each takes its copy from a page file (or site.json) and its items
from a collection.
| Section | Used on |
|---|---|
HomeHeroSection, HomeAboutSection, HomeServicesSection, ImageBand, TestimonialsSection, HomeBlogSection, FaqSection |
Home |
AboutHeroSection, AboutStorySection, LeaderSection |
About |
ClientsSection, IndustriesSection |
Home, About |
ServicesListSection |
Services |
ServiceHeroSection, ServiceIntroSection, ServiceBenefitsSection, ServiceLanesSection |
Service |
HowItWorksSection |
Home, Services, Service |
QuoteFormSection |
Home, Service |
CtaSection |
Home, About, Services, Blog |
BlogListSection |
Blog |
PostArticleSection, RelatedPostsSection |
Blog post |
ContactSection |
Contact |
LegalSection |
The legal pages |
NotFoundSection |
404 |
“How it works”, the industries, the client intro, the call to action and the quote form have the same copy wherever
they appear (howItWorks, industries, clientsIntro, cta and quoteForm in src/content/site.json), so changing
it once changes it everywhere.
QuoteForm.astro is the form itself: QuoteFormSection puts it on a white card beside a photo (Home, Service), and
ContactSection beside the address and the business hours. AboutHeroSection is the title block and the wide photo
under it.
Page maps
Section titled “Page maps”Every page type with each section outlined and labelled: the component that renders it, the file to edit, and where its
copy (src/content/pages/*.json, src/content/site.json) and items (src/content/collections/*.json) come from. Header
and footer take their links and details from src/content/site.json. Photos are the placeholders of the download.
The hero’s lane card is the first lane in lanes.json and its four names the first four clients in clients.json; the
services list shows every service, and the blog the first three posts.

The leader’s message is leader in src/content/pages/about.json; the facts, the industries and the call to action come
from site.json.

Services
Section titled “Services”Each row’s “Key Benefits” are the titles of the service’s benefits.items.

Service
Section titled “Service”The title, photo, the block under it, the key benefits and the lanes come from the service in services.json (its lanes
from lanes.json, by slug); the labels and the photo beside the benefits from src/content/pages/service.json.

Every post is in the page; the list shows six and adds six more each time the spinner under it scrolls into view.

Blog post
Section titled “Blog post”The label above the title is the post’s category. “Other Posts” lists up to three posts of the same category, and is
left out when there are none.

Contact
Section titled “Contact”The address, phone and e-mail come from contact in site.json, the business hours from
src/content/pages/contact.json, the form from quoteForm.

Legal pages
Section titled “Legal pages”One page per entry in legal.json: its title, its date (updated) and its text.

Page not found
Section titled “Page not found”
Reordering or removing a section
Section titled “Reordering or removing a section”Move the lines in the page file, or delete one. To take the FAQ off the home page, delete <FaqSection … /> from
src/pages/index.astro (and its import line); its copy in src/content/pages/home.json can stay or go.
Adding a page
Section titled “Adding a page”-
Add the URL to
src/content/routes.ts:careers: "/careers", -
Add its copy to
src/content/pages/careers.json, with ameta(title, description):{"meta": { "title": "Careers", "description": "Join the Ciketo team: open roles in freight forwarding, operations and customer service across our network." },"label": "Careers","title": "Move the world's cargo with us","text": "We're hiring planners, forwarders and customer service specialists in our offices and ports."} -
Create
src/pages/careers.astro:---import CtaSection from "../components/sections/CtaSection.astro";import careersPage from "../content/pages/careers.json";import siteContent from "../content/site.json";import Section from "../design-system/components/layout/Section.astro";import SectionTitle from "../design-system/components/layout/SectionTitle.astro";import Layout from "../layouts/Layout.astro";---<Layout title={careersPage.meta.title} description={careersPage.meta.description}><Section><SectionTitle as="h1" label={careersPage.label} title={careersPage.title} text={careersPage.text} leadClass="max-w-[450px]" /></Section><CtaSection {...siteContent.cta} /></Layout> -
Link to it: add
{ "label": "Careers", "href": "/careers" }tonavigationinsrc/content/site.json, or to the footer’sfooter.company.links. -
Add it to
src/pages/sitemap.xml.ts, next to the other top-level pages (routes.careersin thepageslist).
A page that should open with a full-width dark photo under a transparent header, like Home and Contact, passes cover
to Layout and puts data-header-cover on its first section (see HomeHeroSection.astro).
Removing a page
Section titled “Removing a page”Delete its file under src/pages/, its entry in navigation, in the footer’s links and in src/pages/sitemap.xml.ts,
and the route in routes.ts. npm run check then tells you about anything still pointing at it through routes.
Buttons in the content link with plain paths ("href": "/contact"): search the content for the path too.
Pages built from a collection
Section titled “Pages built from a collection”src/pages/blog/[slug].astro builds one page per post:
export const getStaticPaths = (async () => { return (await getPosts()).map((post) => ({ params: { slug: post.slug }, props: { post } }));}) satisfies GetStaticPaths;Add a post to src/content/collections/posts.json, and its page, its links and its sitemap entry appear on the next
build; any other slug is a 404. The same pattern builds the service pages (src/pages/services/[slug].astro) and the
legal pages (src/pages/legal/[slug].astro).
The 404 page
Section titled “The 404 page”src/pages/404.astro, with its copy in src/content/pages/not-found.json. It is noindex, like the style guide.
Static hosts serve 404.html for any unknown address.
Search engines
Section titled “Search engines”- Sitemap:
src/pages/sitemap.xml.tsbuildssitemap.xmlfromroutes.tsand the collections: the five main pages, every service, every post (with its date) and every legal page (with itsupdateddate), so new items list themselves. The 404 page and the style guide are left out. - Robots:
src/pages/robots.txt.tsbuildsrobots.txtand points at the sitemap. Both usesite.url, so set your domain before publishing. - Per page: every indexable page gets a title, a description, a canonical link, an
og:urland a share image fromsrc/layouts/Layout.astro. A title that would be longer than 60 characters with| Ciketoappended is shown without the suffix. The home page’s title issite.titlefromsrc/content/site.json, as it is. - Descriptions: the
meta.descriptionof About, Services, Blog and Contact; a service’ssummary; a post’sexcerpt; a legal page’s first paragraph;site.descriptionfor Home and any page without one. Those taken from a service, a post or a legal page are cut at 160 characters with “…”. - Posts are articles for search engines and share cards (
og:typearticlewith their date), and services and posts share their own photo. - Not indexed: the style guide and the 404 page (
noindex).