Files
Peter Meier 1281ed4a6a Add CLAUDE.md with project guidance for Claude Code
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 22:40:22 +01:00

4.5 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

RustyAstro is an Astro + Svelte frontend for RustyCMS (a Rust-based CMS). It fetches all content via REST API, generates TypeScript types from the OpenAPI spec, and deploys as a static site to Firebase Hosting.

Requires: RustyCMS running at PUBLIC_CMS_URL (default http://localhost:3000) for development and build.

Commands

# Development (requires RustyCMS running separately)
yarn dev                    # Generates API types, starts Astro dev server on :4321

# Build
yarn build                  # Generate types → Astro build → Pagefind indexing

# Preview production build
yarn preview

# Type generation (requires RustyCMS running)
yarn generate:api-types     # Regenerate src/lib/cms-api.generated.ts from OpenAPI spec

# Cache management
yarn cache:warm             # Pre-populate .cache/cms/ with all common API responses

# Storybook (UI component development)
yarn storybook              # Start Storybook on :6006

# Deploy
yarn deploy                 # Build + firebase deploy

There are no test commands — this project has no test suite.

Architecture

Data Flow

All content comes from RustyCMS via src/lib/cms.ts. At build time, Astro calls CMS functions in getStaticPaths() to generate static pages. A caching layer makes the build resilient to CMS downtime.

RustyCMS API → cms.ts (process cache + disk cache) → Astro pages → Static HTML

CMS Client (src/lib/cms.ts)

The central module for all API access. Key conventions:

  • slug = URL path (for links, routing)
  • _slug = API/internal ID (for CMS GET requests)
  • Slugs are normalized (leading slashes removed)
  • Caching: in-process deduplication + disk cache at .cache/cms/ (Node.js only, lazy-imported)
  • Dev mode: no list-caching so new CMS entries appear immediately

Generated Types

src/lib/cms-api.generated.ts is auto-generated from the OpenAPI spec — never edit manually. Regenerate with yarn generate:api-types after schema changes in RustyCMS.

Page Routing

  • /src/pages/index.astro — lists all Pages from CMS
  • /:slugsrc/pages/[slug].astro — dynamic page content
  • /post/:slugsrc/pages/post/[slug].astro — blog post detail
  • /blog/ and /posts/ — paginated post lists (both route variants exist)

Content Block System

Pages contain rows of content blocks. Each block type has a corresponding Svelte component in src/components/blocks/. Layout is controlled by src/lib/block-layout.ts using a 12-column Tailwind grid — parent containers need grid grid-cols-12.

i18n / Translations

All UI strings come from a CMS translation bundle, never hardcoded in components.

Flow:

  1. src/middleware.ts loads the app bundle from CMS once per request → Astro.locals.translations
  2. In Astro components: const translations = Astro.locals.translations ?? {}; use t(translations, T.key)
  3. In Svelte (SSR): wrap with <TranslationProvider> and use useTranslate() hook
  4. In client:load islands: useTranslate() has no Svelte context during SSR → pass translations as a prop from the Astro page and use static t(translations, T.key) instead

Translation keys are defined in src/lib/translations.ts as the TRANSLATION_KEYS array (type-safe). Strings are stored in RustyCMS under content/de/translation_bundle/app.json5. Placeholders use {{name}} syntax.

Image Handling

src/lib/rusty-image.ts proxies image transforms through RustyCMS (/api/transform). Transformed images are cached at public/images/transformed/ and survive builds. The RustyImage component exists in both .astro (SSR) and .svelte (client islands) variants.

Layout

src/layouts/Layout.astro is the master layout. It:

  • Wraps content in <TranslationProvider> for Svelte context
  • Loads header navigation and footer from CMS
  • Optionally renders a TopBanner fullwidth image
  • Renders Breadcrumbs (supports both static labels and translation keys)

Environment Variables

Variable Required Purpose
PUBLIC_CMS_URL Yes RustyCMS base URL (no trailing slash)
PUBLIC_SITE_URL No Canonical/sitemap URL (production)
PUBLIC_SITE_NAME No og:site_name and JSON-LD
PUBLIC_UMAMI_SCRIPT_URL No Analytics
PUBLIC_UMAMI_WEBSITE_ID No Analytics

Deployment

Static build deployed to Firebase Hosting. Cache headers: 1-year immutable for assets, 1-hour for HTML. Config in firebase.json and .firebaserc.