Creating New Pages
Relevant source files
The following files were used as context for generating this wiki page:This document outlines the process for creating new pages within the Grapevine website, which is built using Next.js 16 and its App Router. The process leverages file-based routing, standardized component composition, and a centralized system for managing SEO and metadata.
Creating a new page involves creating a new directory within app/, defining the page's content and structure in a page.tsx file, configuring its metadata for SEO, and registering it in the sitemap. This approach ensures consistency and maintainability across the site.
1. File-Based Routing
The project uses Next.js's App Router, where routes are defined by the directory structure inside the app/ folder. To create a new page, you create a new folder and add a page.tsx file within it.
- A folder named
app/example/containing apage.tsxfile will create the route/example. - The root page
/is defined byapp/page.tsx.
Sources: README.md:27-28, app/about/page.tsx, app/product/page.tsx
This diagram illustrates the mapping from the file system to URL routes.
Sources: README.md:27-28, app/sitemap.ts:4-53
2. Page Structure and Composition
Each page is a React Server Component exported as the default from a page.tsx file. The UI is built by composing smaller, reusable components (e.g., <Hero>, <CtaSection>) within the main page component.
Basic Page Template
A new page should follow this basic structure:
import { Metadata } from "next";
// Import necessary components
import Hero from "@/components/hero";
import CtaSection from "@/components/cta-section";
// 1. Define Metadata
export const metadata: Metadata = {
title: "New Page Title",
description: "A concise description of the new page.",
alternates: {
canonical: "/new-page-route",
},
};
// 2. Create the Page Component
export default function NewPage() {
return (
<>
{/* Compose UI using imported components */}
<Hero title="Welcome to the New Page" subtitle="This is a subtitle." />
{/* ... other components ... */}
<CtaSection
title="Ready to learn more?"
buttonText="Contact Us"
buttonHref="/contact"
/>
</>
);
}
Sources: app/about/page.tsx, app/corporate/page.tsx
Root Layout
All pages are wrapped by the RootLayout component defined in app/layout.tsx. This file is responsible for:
- Defining the
<html>and<body>tags. - Applying global styles and fonts (e.g.,
Ambitfont). - Rendering the common
<Header>and<Footer>components. - Injecting site-wide JSON-LD schema for the organization.
The following diagram shows how a page is nested within the root layout.
Sources: app/layout.tsx:109-126
3. Metadata and SEO
SEO is managed through a combination of Next.js's static metadata API and custom JSON-LD schema generation.
Page-Level Metadata
Each page.tsx file should export a metadata object of type Metadata. This object configures the page's <head> tags.
| Property | Type | Description |
|---|---|---|
title | string | The page title. The site name is automatically appended. |
description | string | The meta description for the page. |
keywords | string[] | An array of keywords for the meta keywords tag. |
alternates.canonical | string | The canonical URL for the page. |
Sources: app/product/page.tsx:8-17, app/about/page.tsx:8-14, app/layout.tsx:80-83
Structured Data (JSON-LD)
The site uses lib/seo.ts to generate various schema.org JSON-LD objects. These are injected into the page using the <JsonLd> component.
Key Functions in lib/seo.ts:
generateOrganizationSchema(): Creates schema for the company. Used in the root layout.generateWebPageSchema(): Basic webpage schema.generateSoftwareSchema(): For the product page.generateBreadcrumbSchema(): For breadcrumb navigation.generateServiceSchema(): For service pages like/tmcsand/corporate.generateAboutPageSchema(): For the about page.generateContactPageSchema(): For the contact page.
The following diagram shows the process of generating and rendering SEO data for a page.
Sources: lib/seo.ts, app/product/page.tsx:19-25
Site Configuration
Global SEO settings are stored in siteConfig in lib/seo.ts.
| Property | Description | Example Value |
|---|---|---|
name | Site name | "Grapevine" |
description | Default site description | "Grapevine detects gaps..." |
url | The canonical site URL | https://grapevine.travel |
ogImage | Path to the Open Graph image | "/images/og-image.png" |
xHandle | X (Twitter) handle | "grapevine_trvl" |
Sources: lib/seo.ts:1-16
4. Sitemap Registration
For discoverability by search engines, every new public-facing page must be added to the app/sitemap.ts file. This file exports a function that generates a sitemap.xml file at build time.
Add a new object to the routes array with the following properties:
| Property | Type | Description |
|---|---|---|
url | string | The path of the route (e.g., "/about"). |
lastModified | Date | The date the page was last updated. |
changeFrequency | string | How frequently the page is likely to change. |
priority | number | The priority of this URL relative to other URLs on the site (0.0 to 1.0). |
Example entry for a new page:
// In app/sitemap.ts
const routes = [
// ... existing routes
{
url: "/new-page",
lastModified: new Date(),
changeFrequency: "monthly" as const,
priority: 0.8,
},
];
Sources: app/sitemap.ts:4-53
5. Handling Interactivity
While most pages are React Server Components for performance, pages requiring client-side interactivity (like forms) use components marked with the "use client" directive.
For example, app/contact/page.tsx is a server component, but it imports <ContactForm>, which is a client component.
app/contact/page.tsx: A server component that sets up the page layout and metadata.components/contact-form.tsx: A client component (marked with"use client") that handles state (useState), form events (onSubmit), and API calls (fetch).
This separation allows the static parts of the page to be server-rendered while enabling rich interactivity where needed.
Sources: app/contact/page.tsx:1-29, components/contact-form.tsx:1-296
Summary
Creating a new page is a structured process:
- Create Route: Add a new folder in
app/with apage.tsxfile. - Define Metadata: Export a
metadataobject and use helpers fromlib/seo.tsto generate JSON-LD schemas. - Build UI: Compose the page's UI from existing or new components. Use client components for interactivity.
- Update Sitemap: Add the new route to
app/sitemap.tsto ensure it's indexed by search engines.
This workflow ensures that all new pages are consistent, performant, and SEO-friendly.