Pages

File-based routing. All routes language-prefixed: /[lang]/{path}.

Structure

pages/
├── index.astro          # Root redirect page
└── [lang]/              # Language-prefixed pages
    ├── index.astro
    ├── enrol.astro
    ├── results.astro
    ├── before/          # Pre-race information
    ├── during/          # Race day information
    ├── after/           # Post-race information
    └── info/            # General information

Page Implementation Pattern

All pages must:

  1. Export getStaticPaths() to generate pages for each language
  2. Extract lang from Astro.params
  3. Use useTranslations(lang) for text
  4. Use Layout component or custom HTML structure
  5. Generate page title with translations

Standard Page Template

---
import { useTranslations, languages } from '../../../i18n/utils';
import type { Language } from '../../../i18n/utils';
import Layout from '../../../layouts/Layout.astro';

export function getStaticPaths() {
  return Object.keys(languages).map((lang) => ({
    params: { lang },
  }));
}

const { lang } = Astro.params as { lang: Language };
const t = useTranslations(lang);
const pageTitle = `${t('nav.section.page.title')} | SantYaGo10K 2026`;
---

<Layout title={pageTitle} description={t('nav.section.page.subtitle')} lang={lang}>
  <!-- Hero Section -->
  <section class="relative min-h-[50vh] flex items-center justify-center header-offset">
    <div class="absolute inset-0 bg-gradient-to-br from-{color}-500 to-{color}-600"></div>
    <div class="relative z-10 text-center px-4">
      <h1 class="text-5xl md:text-6xl font-bold text-white mb-4">
        {t('nav.section.page.title')}
      </h1>
      <p class="text-xl text-white/90">
        {t('nav.section.page.subtitle')}
      </p>
    </div>
  </section>

  <!-- Content sections -->
</Layout>

Hero Section Patterns

Pattern 1: Simple Gradient Hero (Centered Text)

Use when: No hero image is available, or for simple informational pages.

<section class="relative min-h-[50vh] flex items-center justify-center header-offset">
  <div class="absolute inset-0 bg-gradient-to-br from-blue-500 to-blue-600"></div>
  <div class="relative z-10 text-center px-4">
    <h1 class="text-5xl md:text-6xl font-bold text-white mb-4">
      {t('section.title')}
    </h1>
    <p class="text-xl text-white/90">
      {t('section.subtitle')}
    </p>
  </div>
</section>

Pattern 2: Two-Column Hero with Image

Use when: You have a featured image to showcase (recommended pattern for main pages).

Example: Track page, Volunteer page.

---
import { Image } from 'astro:assets';
import heroImage from '../../../assets/section/hero.jpg';
---

<!-- Hero Section with Image -->
<section class="relative header-offset py-12 md:py-16">
  <div class="absolute inset-0 bg-gradient-to-br from-orange-400 to-orange-500"></div>
  <div class="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 w-full">
    <div class="grid lg:grid-cols-2 gap-8 items-center">
      <!-- Left: Title and Description -->
      <div>
        <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-4">
          {t('section.title')}
        </h1>
        <p class="text-lg md:text-xl text-white/90">
          {t('section.subtitle')}
        </p>
      </div>

      <!-- Right: Header Image -->
      <div class="relative h-48 md:h-56 lg:h-64 rounded-2xl overflow-hidden shadow-2xl">
        <Image
          src={heroImage}
          alt="Descriptive alt text"
          class="w-full h-full object-cover"
          widths={[400, 800]}
          sizes="(max-width: 768px) 100vw, 50vw"
        />
      </div>
    </div>
  </div>
</section>

Key implementation details:

  1. Image asset organization:

  2. Image optimization:

  3. Responsive heights:

  4. Grid behavior:

  5. Hero section gradients:

Real examples:

Common Section Patterns

Content Section

<section class="py-16 bg-white dark:bg-night-900">
  <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
    <h2 class="text-3xl font-bold text-gray-800 dark:text-white mb-8">
      {t('section.heading')}
    </h2>
    <!-- Content -->
  </div>
</section>

Card Grid

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
  {items.map(item => (
    <div class="bg-neutral-50 dark:bg-night-800 rounded-xl p-6 border-2 border-neutral-200 dark:border-night-600">
      <h3 class="text-xl font-bold text-gray-800 dark:text-white mb-4">
        {item.title}
      </h3>
      <p class="text-gray-600 dark:text-gray-300">
        {item.description}
      </p>
    </div>
  ))}
</div>

Page Creation Checklist

When creating a new page:

Reference Implementation