Timeline & Milestone Objects
Relevant source files
The following files were used as context for generating this wiki page:
Introduction
The Timeline and Milestone objects form a structured content system used to display chronological information within the personal website. These objects allow authors to organize professional experiences, project phases, or educational history into visual lists. The system is designed to be embedded within Portable Text fields of primary documents like Projects and Pages, providing a flexible way to add historical context to content.
Sources: sanity/schemas/documents/project.ts:110-113, sanity/schemas/documents/page.ts:57-60, sanity/schemas/objects/timeline.ts:10-12
Data Models and Schema
The system is built on a hierarchical relationship where a timeline serves as a container for multiple item objects, each of which contains an array of milestone objects.
Milestone Schema
A Milestone is a leaf object containing specific details about a single event or period. It includes fields for a title, description, image, tags, and a mandatory duration.
| Field | Type | Description |
|---|---|---|
title | string | The name of the event/milestone (Required) |
description | string | Detailed text describing the milestone |
image | image | Cover image for the milestone with hotspot support |
tags | array (string) | Categories such as course names or positions |
duration | duration | Start and end dates (Required) |
Sources: sanity/schemas/objects/milestone.ts:6-48, sanity.types.ts:41-52
Timeline Schema
The Timeline object acts as a wrapper. In the Sanity Studio, it is restricted to a maximum of 2 top-level items to maintain layout integrity within the website's body.
| Field | Type | Constraints |
|---|---|---|
items | array | Max 2 items allowed |
items.title | string | Title for the specific timeline column |
items.milestones | array (milestone) | List of milestone objects |
Sources: sanity/schemas/objects/timeline.ts:10-40, sanity.types.ts:18-30
Relationship Diagram
The following diagram illustrates the structural hierarchy from a Project document down to individual Milestones.
Frontend Implementation
The rendering of these objects is handled by two primary React components: TimelineSection and TimelineItem.
TimelineSection Component
This component serves as the layout container. It maps through the timeline items and renders them in a responsive flex layout (columns on mobile, rows on desktop). It utilizes OptimisticSortOrder and createDataAttribute to support Sanity's Visual Editing/Presentation mode.
Sources: components/TimelineSection.tsx:16-64
TimelineItem Component
The TimelineItem handles the visual representation of a single milestone. It extracts the start and end years from the duration object and displays a vertical line between items to create the visual "timeline" effect.
Component Data Structures
The TypeScript interfaces define the expected shape for frontend props:
export interface MilestoneItem {
_key: string
description?: string
duration?: {
start?: string
end?: string
}
image?: Image
tags?: string[]
title?: string
}
Sources: types/index.ts:4-14
Integration with Primary Documents
Timeline objects are integrated into the project via defineArrayMember within the Portable Text configuration of project and page documents. This allows editors to insert a timeline anywhere within the main content flow.
Project Document Integration
defineField({
name: 'description',
title: 'Project Description',
type: 'array',
of: [
defineArrayMember({ type: 'block' }),
defineArrayMember({
name: 'timeline',
type: 'timeline',
}),
// ... other members
],
})
Sources: sanity/schemas/documents/project.ts:90-114
Page Document Integration
Similarly, the page schema includes timeline as an allowed member of the body field array.
Sources: sanity/schemas/documents/page.ts:41-61
Conclusion
The Timeline & Milestone system provides a highly structured yet flexible way to represent chronological data. By leveraging Sanity's object nesting and custom React components, the project maintains strict data validation (such as the 2-item limit) while ensuring a consistent visual experience across different document types like Projects and Pages.
Sources: sanity/schemas/objects/timeline.ts:16, components/TimelineSection.tsx:28