Pages and sections — Titen Next.js
A page is a small file that picks sections and hands them content. src/app/blog/page.tsx is the whole Blog page:
export const metadata = pageMeta(routes.blog, blogPage.meta);
export default async function BlogPage() { const posts = await getPosts(); return <BlogListSection label={blogPage.label} title={blogPage.title} posts={posts.map(toPostCard)} />;}pageMeta(route, meta)gives the page its browser title, description, canonical link and share image.getPosts()reads the collection (see Editing the content).toPostCardturns each post into what the card shows (src/lib/to-ui.ts).- The section renders them.
The sections you can use
Section titled “The sections you can use”In src/components/sections/. Each takes its copy from a page file (or site.ts) and its items from a collection.
Sections that belong to one page share a file: AboutSections.tsx holds every About section.
| Section | File | Used on |
|---|---|---|
HomeHeroSection, HomeAboutSection, HomeProjectsSection, HomeServicesSection, CtaSection, HomeBlogSection |
one file each | Home |
AboutHeroSection, BeginningsSection, ApproachSection, VideoSection, TeamSection, AwardsSection |
AboutSections.tsx |
About |
ProjectsListSection |
ProjectsListSection.tsx |
Projects |
CategorySection |
CategorySection.tsx |
Residential, Hospitality, Commercial |
ProjectHeroSection, ProjectStorySection, RelatedProjectsSection |
ProjectSections.tsx |
Project |
ServicesListSection, ProjectsCtaSection |
ServicesSections.tsx |
Services |
ServiceMainSection |
ServiceMainSection.tsx |
Service |
BlogListSection, PostMainSection, MorePostsSection |
BlogSections.tsx |
Blog, blog post |
TestimonialsListSection, ServicesOverviewSection |
TestimonialsSections.tsx |
Testimonials |
ContactMainSection, ContactSalesSection |
ContactSections.tsx |
Contact |
ContactFormSection |
ContactFormSection.tsx |
Projects, the category pages, Service |
NotFoundSection |
NotFoundSection.tsx |
404 |
ContactFormSection (“Let’s Work Together”) appears on five kinds of page with the same copy (projectForm in
src/content/site.ts), so changing it once changes it everywhere. The dark “Let’s Talk!” block above every footer is
part of the footer (src/components/site/Footer.tsx, copy in footer.cta).
ProjectMosaic.tsx holds the two project layouts the sections share: the mosaic of six cards (Home, Projects) and the
three-column grid.
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/*.ts) and items (src/content/collections/*.ts) come from. Header and footer take their links
and details from src/content/site.ts. Photos are the placeholders of the download.

The team and the awards are in src/content/pages/about.ts (team.members, awards.items).

Projects
Section titled “Projects”
A project category
Section titled “A project category”The page’s title is the category’s name; its projects are the ones whose category is its slug, the first one shown
wide.

Project
Section titled “Project”
Services
Section titled “Services”
Service
Section titled “Service”The title, image, “About the service” and “What’s included” come from the service in services.ts; the headings and the
brochure button from src/content/pages/service.ts.


Blog post
Section titled “Blog post”
Testimonials
Section titled “Testimonials”
Contact
Section titled “Contact”
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 blog off the home page, delete <HomeBlogSection … /> from
src/app/page.tsx; its copy in src/content/pages/home.ts 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.ts, with ameta(title, description):export const careersPage = {meta: { title: "Careers", description: "Join the Titen studio: open roles in architecture, interiors and project management." },label: "Careers",title: "Build the future with us",}; -
Create
src/app/careers/page.tsx:import { Section, PageTitle } from "@/design-system";import { ContactFormSection } from "@/components/sections/ContactFormSection";import { careersPage } from "@/content/pages/careers";import { routes } from "@/content/routes";import { projectForm } from "@/content/site";import { submitContact } from "@/lib/actions";import { pageMeta } from "@/lib/meta";export const metadata = pageMeta(routes.careers, careersPage.meta);export default function CareersPage() {return (<><Section><PageTitle label={careersPage.label} title={careersPage.title} /></Section><ContactFormSection {...projectForm} action={submitContact} /></>);} -
Link to it: add
{ label: "Careers", href: routes.careers }tonavigationinsrc/content/site.ts, or to the footer’sstudio.links. -
Add it to
src/app/sitemap.ts, next to the other top-level pages.
Category pages live at the top level (/residential), so a new page must not share its URL with a category’s slug.
Removing a page
Section titled “Removing a page”Delete its folder under src/app/, its entry in navigation, in the footer’s links and in src/app/sitemap.ts, and
the route in routes.ts. npm run build then tells you about anything still linking to it through routes.
Pages built from a collection
Section titled “Pages built from a collection”src/app/blog/[slug]/page.tsx builds one page per post:
export const dynamicParams = false; // only the slugs below exist; anything else is a 404export async function generateStaticParams() { return (await getPosts()).map((post) => ({ slug: post.slug }));}Add a post to src/content/collections/posts.ts, and its page, its links and its sitemap entry appear on the next
build. The same pattern builds the project, service and category pages (src/app/[category]/page.tsx).
The 404 page
Section titled “The 404 page”src/app/not-found.tsx, with its copy in src/content/pages/not-found.ts. It is noindex, like the style guide.
Search engines
Section titled “Search engines”- Sitemap:
src/app/sitemap.tsbuildssitemap.xmlfromroutes.tsand the collections, so new items list themselves. The 404 page and the style guide are left out. - Robots:
src/app/robots.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 frompageMeta(src/lib/meta.ts). A title that would be longer than 60 characters with| Titenappended is shown without the suffix. - Not indexed: the style guide and the 404 page (
noindex).
The header search
Section titled “The header search”“Search projects” in the header looks through the project pages: titles first, then the text of every project. The
list is built in src/app/layout.tsx from getProjects(). To search posts too, add them to searchItems there with
title, href and text.