Working with Static Data
Relevant source files
The following files were used as context for generating this wiki page:The Grapevine website application employs a clear strategy for managing static data, separating content and configuration from the presentational logic of React components. This approach centralizes key information, making the site easier to maintain and update. Data is primarily managed through TypeScript files that export constants, arrays, and structured objects. These are then imported into page and layout components for rendering. This documentation outlines the different patterns used for handling static data, from global site configuration to page-specific content.
Core Site Configuration & SEO
Global site configuration and data for Search Engine Optimization (SEO) are centralized in lib/seo.ts. This file acts as a single source of truth for metadata, SEO schema definitions, and generator functions.
Site Configuration
A constant object, siteConfig, holds all top-level site information. This includes the site name, description, URL, social media handles, and keywords. This object is consumed by the root layout and other parts of the application to ensure consistency.
Sources: lib/seo.ts:1-21, app/layout.tsx:80-111
The following table details the properties of the siteConfig object.
| Property | Type | Description |
|---|---|---|
name | string | The name of the site ("Grapevine"). |
description | string | The default meta description for the site. |
url | string | The base URL of the application. |
ogImage | string | Path to the Open Graph image. |
xHandle | string | The site's handle on X (formerly Twitter). |
linkedInUrl | string | The URL for the company's LinkedIn page. |
locale | string | The site's locale (e.g., "en_GB"). |
keywords | string[] | An array of default SEO keywords. |
Sources: lib/seo.ts:1-21
SEO Schema Management
The lib/seo.ts file defines TypeScript interfaces for various schema.org types, such as OrganizationSchema, WebPageSchema, and FAQSchema. These interfaces ensure that the JSON-LD data generated is type-safe and adheres to the expected structure.
This diagram illustrates the structure of some key schema interfaces.
Sources: lib/seo.ts:23-90
Generator functions (e.g., generateOrganizationSchema, generateWebPageSchema) are used to create the final JSON-LD objects. These functions often pull data from the siteConfig object to populate the schema. Page components then call these generators and pass the resulting data to the <JsonLd /> component for injection into the HTML head.
The following sequence diagram shows the flow for generating and rendering schema data on a page.
Content Data Structures
For reusable content blocks, such as feature lists, the application uses dedicated data files. This pattern is exemplified by data/features.ts, which exports data consumed by the <Features /> component.
Feature Data
The data/features.ts file exports arrays of objects, featureSteps and pillars, which define the content for different sections of the Features component.
// Example structure from data/features.ts
export const featureSteps = [
{
label: "Step 1",
title: "Detect",
description:
"Grapevine connects to your booking data in real time, identifying trips with missing hotels, transfers, or other ancillaries.",
icon: "plane",
},
// ... more steps
];
Sources: data/features.ts is not in the context, but its usage is shown in app/page.tsx:10, app/tmcs/page.tsx:5, and app/corporate/page.tsx:6. The structure is inferred from its consumption in components/features.tsx.
Data Consumption Flow
This data is imported by various page components and passed as props to the <Features /> component, which is responsible for rendering it.
This diagram shows the flow of feature data from its definition to rendering.
Sources: app/page.tsx:10, 70, components/features.tsx
Page-Specific Static Data
For content that is unique to a single page, the static data is often defined directly within the page component file itself. This keeps related logic and content co-located when reusability is not a concern.
Examples include:
- The
sectionsarray inapp/page.tsx, which defines the content for the<AlternatingContent />component on the homepage. - The
groupsarray inapp/about/page.tsx, which contains the data for team members and advisors.
The structure for an item in the sections array on the homepage is as follows:
| Property | Type | Description |
|---|---|---|
title | string | The title of the content block. |
items | object[] | An array of list items, each with a text and icon. |
image | string | The path to the associated image. |
buttonText | string (optional) | Text for a call-to-action button. |
buttonHref | string (optional) | The URL for the button's link. |
Sources: app/page.tsx:15-62
Component-Level Static Data
Some components define their own static data, either as internal constants or as default props. This makes the components self-contained and provides sensible defaults.
Footer Links
The <Footer /> component defines its navigation links as internal constant arrays. This makes it easy to update the footer links directly within the component file.
// Snippet from components/footer.tsx
const legalLinks = [
{ label: "Privacy Policy", href: "/policy/privacy" },
{ label: "Cookies Policy", href: "/policy/cookies" },
];
Sources: components/footer.tsx:19-22
Default Component Props
The <StatsSection /> component defines a stats array as a default value for its stats prop. If a parent component does not provide this prop, the default static data is used, ensuring the component always has content to render.
Static Page Content
For pages with large amounts of static text, such as legal policies, the content is written directly in JSX within the page component. While less structured than data objects, this is a straightforward approach for content-heavy pages that do not require dynamic data. Pages like app/policy/terms/page.tsx and app/acceptable-use-policy/page.tsx exemplify this pattern.
Sources: app/policy/terms/page.tsx:18-219, app/acceptable-use-policy/page.tsx:17-130
Summary
The project utilizes several effective patterns for managing static data, chosen based on the scope and reusability of the information.
- Centralized Configuration:
lib/seo.tsfor global site data and SEO. - Dedicated Data Files:
data/features.tsfor content shared across multiple components. - Page-Level Definitions: For content unique to a single page, data is defined within the page component itself.
- Component-Level Defaults: Self-contained components provide their own default static data.
- Hardcoded JSX: For simple, text-heavy pages, content is written directly in the component's return statement.
This layered approach ensures that data is managed in a logical, maintainable, and scalable way.
Sources: lib/seo.ts, data/features.ts, app/page.tsx, components/footer.tsx, app/policy/terms/page.tsx