← Back to site

Managing Page Text

Page text files let you edit headings, descriptions, buttons, and other copy across the website without touching code. They are stored in src/content/page-text/.

How It Works

Each .mdx file provides text for a specific section of a page. You only edit the frontmatter (the YAML between the --- lines) — the body of these files is not used.

When a page loads, its component fetches the matching content file by ID and renders the fields into the page. If a file is missing or a field is left out, the section will either hide that element or fall back to a default — nothing will break.

Folder Structure

Files are organized by locale, then by page. Each locale subfolder (en/ and de/) has the same internal structure:

src/content/page-text/
├── en/                      ← English (default)
│   ├── landing/             — Homepage sections (intro, testimonials, etc.)
│   ├── about-us/            — About Us page (mission, benefits, etc.)
│   ├── events/              — Events page (header, intro, crosslinks)
│   ├── projects/            — Projects page (header, categories, crosslinks)
│   ├── sponsors/            — Sponsors page (header, tiers, CTAs)
│   ├── contact/             — Contact page
│   ├── footer/              — Footer (address)
│   ├── site/                — Site metadata (title, description)
│   ├── media/               — Media page (page header + categories list)
│   ├── 404/                 — Not Found page
│   ├── imprint/             — Imprint page
│   ├── datenschutz/         — Privacy policy page
│   ├── hero.mdx              — Landing hero (CTAs)
│   ├── faq.mdx               — About Us FAQ
│   ├── nav-columns.mdx       — Footer multi-column navigation
│   ├── social.mdx            — Social media links (site-wide)
│   ├── donate.mdx            — Sponsors page donate card
│   └── nav-links/           — Flat navigation link lists
│       ├── header.mdx        — Header nav
│       └── footer-bottom.mdx — Footer bottom bar
└── de/                      ← German translations (same structure as en/)
    ├── landing/
    ├── about-us/
    └── ...

Both en/ and de/ folders use identical structure. If a German translation is missing, the English version is shown automatically on /de/ pages.

Naming conventions:

  • Page hero/header files end in -title (e.g., events/events-title, about-us/about-us-title)
  • Crosslink sections end in -crosslink (e.g., events/events-crosslink, projects/projects-crosslink)
  • Empty-state messages end in -empty-state (e.g., events/events-empty-state)
  • Regular section files are named after the section they control (e.g., about-us/our-mission)
  • “Outlier” shapes (FAQ, hero, social, donate, etc.) live as single files at the locale root so the CMS can surface them through dedicated editor forms

Available Fields

Every file must have a title. All other fields are optional — each file uses only the fields its section needs.

FieldTypeDescription
titlestring (required)Section heading
subtitlestringSecondary heading, label, or tagline displayed above or below the title
descriptionstringParagraph text (intro copy, explanations)
seoDescriptionstringMeta description for search engines (~150 characters)
buttonTextstringPrimary button label (pair with buttonHref)
buttonHrefstringPrimary button link URL (pair with buttonText)
secondButtonTextstringSecondary button label (pair with secondButtonHref)
secondButtonHrefstringSecondary button link URL (pair with secondButtonText)
instagramButtonTextstringLabel for the “Follow us on Instagram” button
ctasarrayCall-to-action cards (max 4), each with title, description, href
itemsarrayList of strings (for addresses, benefits, tiers — see below)
faqsarrayFAQ entries, each with question and answer (answers support Markdown)
socialLinksarraySocial media links, each with platform (id of an entry in the Social platforms collection), url, optional hoverColor override
navLinksarraySimple navigation links, each with label and href
navColumnsarrayMulti-column navigation, each with heading, href, and nested links
accountHolderstringDonation: account holder name (donate card)
bankNamestringDonation: bank name
ibanstringDonation: IBAN for bank transfers
bicstringDonation: BIC / SWIFT code
referencestringDonation: suggested transfer reference
paypalUrlstringDonation: full PayPal donation URL (pair with paypalButtonText)
paypalButtonTextstringDonation: PayPal button label (pair with paypalUrl)
roomstringAbout Us “Where to find us”: large room/building label
schedulestringAbout Us “Where to find us”: meeting time
mapLatnumberLatitude of the pin on the About Us “Where to find us” map
mapLngnumberLongitude of the pin on the About Us “Where to find us” map
rememberLabelstringAbout Us “Where to find us”: small uppercase label above the room/schedule (e.g. “remember:“)
emailLabelstringContact page: heading on the email card
addressLabelstringContact page: heading on the address card
mapLinkTextstringContact page: text on the link below the address that jumps to the map
followLabelstringContact page: heading on the social-links card
showMoreTextstringLanding page “Latest news”: mobile-only button that expands the list
showLessTextstringLanding page “Latest news”: mobile-only button that collapses the list
orDividerTextstringSponsors page: small uppercase label between the sponsor CTA and the donation block (e.g. “Or”)
bankToggleTextstringSponsors page: label on the button that expands the bank transfer details

Patterns & Examples

Below is every type of content file used on the site, with a full example and explanation of where it appears.


Page Hero Header

Controls the main title and subtitle at the top of a page. Most pages have one of these. Include seoDescription to set the page’s <meta name="description"> tag for search engines.

---
title: "Events"
subtitle: "Join us for workshops, hackathons, and networking opportunities"
seoDescription: "Upcoming BEARS events and workshops at TU Berlin."
---

Where it appears: The large heading and subtitle shown at the very top of a page.

Fields used: title, subtitle, seoDescription

Files: events/events-title, projects/projects-title, sponsors/sponsors-title, about-us/about-us-title, contact/contact-title. The media page’s header is combined with its category list — see the Media Page Categories section below.


Heading + Description + Button

The most common pattern. Used for section introductions and crosslinks that direct visitors to another page.

---
title: "What is BEARS e.V.?"
description: "We are a student team at TU Berlin building rockets, satellites, and more. Our members gain hands-on experience in aerospace engineering."
buttonText: "Learn More"
buttonHref: "/about-us"
---

Where it appears: Standalone sections on the homepage, intro paragraphs on content pages, and crosslink banners at the bottom of pages (“Want to see our projects? →”).

Fields used: title, description (optional), buttonText + buttonHref (optional, always used as a pair), secondButtonText + secondButtonHref (optional second button, used in landing/latest-news), instagramButtonText (optional, only in landing/latest-news), showMoreText + showLessText (optional, only in landing/latest-news — label the mobile Show more / Show less toggle)

Files: landing/what-is-bears, landing/latest-news, landing/become-sponsor, events/events-intro, events/events-crosslink, projects/projects-crosslink, sponsors/sponsors-intro, sponsors/sponsors-crosslink, sponsors/become-sponsor-cta

landing/what-is-bears — carousel images: The English version of this page also has a Carousel images field with reorderable image uploads. Those images appear in the marquee below the text on both the English and German landing pages, so you only maintain them once (on the English page). Editing the German singleton will not affect the carousel.


Subtitle + Title + Description (Mission Statement)

Some sections display a small label above the main heading for visual hierarchy. The subtitle field serves as this label.

---
title: "Our Mission"
subtitle: "This is"
description: "We bridge the gap between the classroom and the launchpad. At BEARS, students design, build, and launch real aerospace systems — from sounding rockets to scientific payloads."
---

Where it appears: The “Our Mission” section on the About Us page. The subtitle renders as a small accented label above the title (e.g., THIS IS Our Mission, where “THIS IS” is the subtitle in the site’s accent color).

Fields used: subtitle, title, description, buttonText + buttonHref (optional pair — about-us/our-mission uses these to render the “Join us!” button that jumps down to the Find Us section)

Files: about-us/our-mission, landing/testimonials


Contact Details (Email + Multi-line Address)

A standalone entry that holds the public email and postal address. Both the Contact page’s email/address cards and the site footer’s address block read from here, so editing it in one place updates both surfaces.

---
title: "Contact details"
email: "info@bears-space.de"
address: |-
  Berlin Experimental Astronautics
  Research Student team e.V.
  c/o TU Berlin - Institut für Luft- und Raumfahrt
  Marchstraße 12-14
  10587 Berlin
---

Where it appears: The Contact page cards (email + address) and the site footer’s address block. Each line in address renders as a separate line. title is an internal label for the CMS — it is not rendered on the site.

Fields used: title, email, address, emailLabel (heading on the email card), addressLabel (heading on the address card), mapLinkText (text for the link below the address that jumps to the map)

Files: contact-details


Items List (Simple Strings)

A plain list of strings, useful for short content blocks or any ordered set of text lines.

---
title: "Reach us directly"
items:
  - "Email: contact@bears-space.de"
  - "Phone: +49 30 000 0000"
---

Where it appears: Contact information block. Each item is rendered as a separate line.

Fields used: title, items

Files: contact/contact-info


Find Us (Room + Schedule + Map Pin)

The About Us “When and where to find us” section. A heading/description plus three pieces of location info: the room label, the meeting time, and the coordinates of the map pin.

---
title: "When and where to find us!"
subtitle: "You want a sneak peak?"
description: "We meet weekly in room F11 of the ILR building at TU Berlin. Drop by — no sign-up required."
room: "Room F11 in ILR"
schedule: "every Tuesday at 6 PM"
mapLat: 52.5154444
mapLng: 13.3238611
---

Where it appears: The two-column “Where to find us” section on the About Us page. room renders as the large label next to the map, schedule as the line beneath it. The map on the right is centered on the coordinates with a red pin.

Finding the coordinates: Open google.com/maps, right-click the spot you want to pin, and the first two numbers in the popup are the latitude and longitude — copy them straight into mapLat and mapLng.

Fields used: title, subtitle (optional label above heading), description (optional intro text), room, schedule, mapLat, mapLng, rememberLabel (small uppercase label above the room/schedule)

Files: about-us/find-us


Titled Items List

A richer list format where each item has its own title and optional description. The component renders each as a numbered card with a bold title and lighter description text.

---
title: "What's in it for you?"
titledItems:
  - title: "Hands-on Engineering"
    description: "Design, manufacture, and test real rocket systems — from propulsion to avionics and recovery."
  - title: "Industry Connections"
    description: "Build your network through partnerships with aerospace companies and research institutions."
  - title: "Team Leadership"
    description: "Take ownership of subsystems and lead cross-functional teams on ambitious projects."
---

Where it appears: The “What’s in it for you?” benefits grid on the About Us page. Each entry becomes a card with a numbered label, a bold title, and a description.

Fields used: title, titledItems (each with title and optional description)

Files: about-us/whats-in-it


A dedicated shape for the sponsors page, with one short description per tier. Each tier has its own named field, so editors see five labeled inputs rather than an ordered array.

---
title: "Our Sponsors"
tierDescriptions:
  diamond: "Our Diamond partners drive our most ambitious aerospace projects forward."
  platinum: "Platinum sponsors provide critical support for our research and development."
  gold: "Gold sponsors help fund our engineering workshops and educational programs."
  silver: "Silver sponsors contribute to our growing aerospace community."
  bronze: "Bronze supporters help us maintain our workshop space and tools."
---

Where it appears: The tier accordions in the sponsor showcase. Each tier’s description renders above the logos for that tier.

Fields used: title, tierDescriptions.{diamond,platinum,gold,silver,bronze}

Files: sponsors/sponsor-tiers


FAQs

Expandable question-and-answer sections rendered as an accordion. Answers support Markdown formatting, so you can use bold text, links, and lists inside them.

---
title: "Frequently Asked Questions"
subtitle: "Got Questions?"
description: "Everything you need to know about joining and participating in BEARS e.V."
buttonText: "Get in touch"
buttonHref: "/contact"
faqs:
  - question: "How can I join BEARS e.V.?"
    answer: "Just show up to one of our weekly meetings! We welcome all TU Berlin students, regardless of their field of study or experience level. Check the **Find Us** section above for our meeting time and location."
  - question: "Do I need prior aerospace experience?"
    answer: "Not at all! Our members come from diverse backgrounds — mechanical engineering, computer science, physics, and more. We provide training and mentoring so you can learn as you go."
  - question: "Are there membership fees?"
    answer: "BEARS e.V. charges a small annual membership fee to cover materials and operational costs. Financial constraints should never prevent you from joining — reach out to us if you have concerns."
  - question: "How can my company sponsor BEARS?"
    answer: "We are always looking for sponsors! Visit our [Sponsors page](/sponsors) or [get in touch](/contact) directly to discuss partnership opportunities."
---

Where it appears: The FAQ section on the About Us page. Each FAQ becomes a collapsible accordion item. The buttonText/buttonHref creates a “Still have questions?” link below the accordion.

Markdown in answers: You can use:

  • **bold text** for emphasis
  • [link text](/path) for internal links
  • [link text](https://example.com) for external links
  • - item for bullet lists

Fields used: title, subtitle (optional label above heading), description (optional intro text), buttonText + buttonHref (optional CTA link), faqs

File: faq.mdx (at the locale root). Edited in the CMS via the FAQ singleton.


CTA Cards (Hero)

The homepage hero section displays up to 4 call-to-action cards. Each card has a title, a short description, and a link. The subtitle field sets the tagline displayed below the BEARS logo.

---
title: "Hero Cards"
subtitle: "Berlin Experimental Astronautics Research Student Team e.V."
seoDescription: "BEARS e.V. – Student aerospace team at TU Berlin building rockets, satellites, and more."
ctas:
  - title: "How to Join"
    description: "Becoming a member of Bears e.V."
    href: "/about-us#find-us-section"
  - title: "Our Projects"
    description: "Explore what we are working on"
    href: "/projects"
  - title: "Events"
    description: "Upcoming workshops and meetups"
    href: "/events"
  - title: "Contact Us"
    description: "Get in touch with the team"
    href: "/contact"
---

Where it appears: The animated hero section on the homepage. Each CTA becomes a glass-style card with a hover glow effect.

Important: You can have between 0 and 4 CTA cards. The grid layout adjusts automatically. If you remove all CTAs, only the logo and subtitle are shown.

Link paths: Always write href values without a /de/ prefix (e.g., /projects, not /de/projects). The code automatically adds the correct locale prefix when rendering the German version of the page.

Fields used: title (not displayed, used internally), subtitle (hero tagline), seoDescription (homepage meta description), ctas (each with title, description, href)

File: hero.mdx (at the locale root). Edited in the CMS via the Landing hero singleton.


The direct-donations block on the Sponsors page, shown below the “Partner with BEARS” sponsor CTA and separated from it by an “OR” divider. It’s a secondary path for individuals who want to support BEARS directly, while sponsorship stays the primary call.

---
title: "Support us directly"
description: "Help us build and launch real rockets. Every contribution funds student-built aerospace projects — from first prototype to competition launch."
items:
  - "Rocket hardware"
  - "Lab equipment"
  - "Competition travel"
accountHolder: "BEARS e.V."
bankName: "Your bank name"
iban: "DEXX XXXX XXXX XXXX XXXX XX"
bic: "XXXXXXXXXXX"
reference: "Donation"
paypalUrl: "https://www.paypal.com/donate/?hosted_button_id=..."
paypalButtonText: "Donate via PayPal"
---

Where it appears: The Sponsors page, directly below the “Partner with BEARS” sponsor CTA. A subtle gradient “OR” divider visually bridges the two cards. The donate card is narrower and quieter than the sponsor card above it, intentionally secondary in the visual hierarchy.

Card structure (top to bottom):

  1. A small heading (uses title)
  2. A short description (description)
  3. A row of three value labels with icons (from items — icons are hardcoded in the page template, labels are editable here)
  4. Two buttons side-by-side: “Donate via PayPal” (primary) and “Bank transfer details” (secondary, expands the bank block)
  5. An expandable bank transfer details panel (only shown when the button is clicked)

Partial fields are fine:

  • The bank details block only renders if at least one of accountHolder, bankName, iban, bic is present. Each row inside the block is only shown if its field is set.
  • The PayPal button only renders if both paypalUrl and paypalButtonText are provided — same pairing rule as buttonText/buttonHref.
  • The value trio (items) only renders if the array has at least one entry. You can have fewer or more than three items.

Fields used: title, description, items, accountHolder, bankName, iban, bic, reference, paypalUrl, paypalButtonText, orDividerText (label on the divider between the sponsor CTA and the donate card, e.g. “Or”), bankToggleText (label on the button that expands the bank details)

File: donate.mdx (at the locale root). Edited in the CMS via the Donate singleton.

Jump target: The donate card has a stable anchor #donate-title, used by the “Donate” link in the footer’s Sponsors column.


The single source of truth for all social media links across the website. This file is used by the Footer, Contact page, LatestNews section (Instagram CTA), and the structured data (schema.org Organization sameAs).

Each entry picks a platform from the Social platforms collection and sets a url. The icon and default hover color live on the platform entry, not on the Social link — editors never re-upload an icon for an existing platform. You can optionally override the hover color per entry.

---
socialLinks:
  - platform: "instagram"
    url: "https://www.instagram.com/bears.space/"
  - platform: "linkedin"
    url: "https://www.linkedin.com/company/bears-ev/"
    hoverColor: "#0A66C2"
  - platform: "youtube"
    url: "https://www.youtube.com/@BEARS-Space"
---

Where it appears: The social media icon row in the Footer and Contact page, the Instagram CTA link on the homepage, and the sameAs array in structured data.

Adding a new platform: In the CMS, go to Social platforms (grouped under “Contact & social”), click Add, pick an ID (e.g. bluesky), upload the SVG icon, and set an optional default hover color. Save. The new platform immediately appears in the Platform dropdown on every Social link entry — no code change required.

platform: Required. The id of an entry in the Social platforms collection. Drives the icon, default hover color, and accessible label.

hoverColor: Optional per-entry override. Leave blank to use the platform’s default hover color (or the site accent if the platform doesn’t define one). Use standard hex color codes (e.g. "#0A66C2" for LinkedIn blue).

Fields used: socialLinks, followLabel (heading on the “Follow Us” card on the Contact page)

File: social.mdx (at the locale root). Edited in the CMS via the Social links singleton.


Header Navigation

Controls the top navigation bar links shown on every page. Each entry has a label (displayed text) and an href (link target).

---
title: "Header Navigation"
navLinks:
  - label: "Projects"
    href: "/projects"
  - label: "Sponsors"
    href: "/sponsors"
  - label: "Events"
    href: "/events"
  - label: "About Us"
    href: "/about-us"
  - label: "Contact"
    href: "/contact"
---

Where it appears: The main navigation bar at the top of every page (desktop menu and mobile hamburger menu).

Reordering or removing links: The links appear in the order listed. Remove an entry to hide it from the nav, or rearrange entries to change the order.

Fields used: title (not displayed), navLinks (each with label and href)

File: nav-links/header.mdx. Edited in the CMS via the Nav link lists collection.


Defines the footer’s multi-column link layout. Each column has a heading (which is also a link), and a list of sub-links beneath it.

---
title: "Footer Navigation"
navColumns:
  - heading: "Projects"
    href: "/projects"
    links:
      - label: "Current Projects"
        href: "/projects?status=ongoing#what-we-build"
      - label: "Experimental Rocketry"
        href: "/projects?category=experimental-rocketry#what-we-build"
      - label: "Past Projects"
        href: "/projects?status=completed#what-we-build"
  - heading: "Events"
    href: "/events"
    links:
      - label: "Upcoming Events"
        href: "/events?date=upcoming#whats-happening"
      - label: "Past Events"
        href: "/events?date=past#whats-happening"
  - heading: "About Us"
    href: "/about-us"
    links:
      - label: "Our Team"
        href: "/about-us#faces-of-bears-title"
      - label: "Media"
        href: "/media"
      - label: "Contact"
        href: "/contact"
      - label: "FAQ"
        href: "/about-us#faq-title"
---

Where it appears: The multi-column navigation grid in the footer.

Link format: Links can include query parameters and hash fragments to deep-link to filtered views or specific sections (e.g., /events?date=upcoming#whats-happening).

Fields used: title (not displayed), navColumns (each with heading, href, and links array of label + href)

File: nav-columns.mdx (at the locale root). Edited in the CMS via the Footer navigation singleton.


Controls the copyright text and legal page links at the very bottom of the footer.

---
title: "© {year} BEARS e.V. All rights reserved."
navLinks:
  - label: "Imprint"
    href: "/imprint"
  - label: "Privacy Policy"
    href: "/datenschutz"
---

Where it appears: The thin bar at the bottom of every page.

{year} placeholder: The title field supports a {year} placeholder that is automatically replaced with the current year at build time. Write it exactly as {year}.

Fields used: title (copyright text with optional {year} placeholder), navLinks (legal page links)

File: nav-links/footer-bottom.mdx. Edited in the CMS via the Nav link lists collection.


Site Metadata

Sets the default site title and description used in <title> tags and as fallback meta descriptions across the site.

---
title: "BEARS e.V."
description: "BEARS e.V. – Berlin Experimental Astronautics Research Student team at TU Berlin. Building rockets, satellites, and more."
---

Where it appears: The browser tab title and default meta description when a page does not provide its own seoDescription.

Fields used: title, description

Files: site/metadata


Empty States

Shown when a content list (events, projects) has no items to display. Provides a friendly message instead of a blank page.

---
title: "No events right now"
description: "Check back soon — we're always planning something new!"
---

Where it appears: The events or projects page when there are no entries matching the current filter.

Fields used: title, description

Files: events/events-empty-state, projects/projects-empty-state


Media Page Categories

Controls which image categories appear on the Media page, their display order, and their labels. Each entry has an id (matching a known image directory) and a label (the displayed title).

The Media page is split across two files: media/media-title.mdx holds the page header (title, subtitle, SEO description, hero image) and media/media-categories.mdx holds the category list.

---
mediaCategories:
  - id: all
    label: "All"
  - id: events
    label: "Events"
  - id: projects
    label: "Projects"
  - id: what-is-bears
    label: "What is BEARS"
---

Where it appears: The Media page. Each category becomes a collapsible accordion section showing images from that directory.

Available IDs:

IDImages from
allCombined images from all other listed categories (special)
about-usAbout Us page images (src/assets/about-us/our-mission/)
eventsEvent cover images (src/assets/events/)
peoplePerson portraits — Faces of BEARS, Meet the Team, and Testimonials (src/assets/people/)
heroAll hero images across pages (src/assets/hero/)
projectsProject cover images (src/assets/projects/)
what-is-bearsWhat is BEARS images (src/assets/whatIsBears/)

Controlling the page:

  • Show/hide categories: Add or remove entries from the list. Only listed categories appear.
  • Reorder categories: The display order matches the list order in the file.
  • Rename categories: Change the label to set the displayed title (this is translated per locale).
  • “All” category: When all is in the list, it combines images from all other listed categories. Remove it to hide the combined view.
  • Categories with no images are automatically hidden.

Fields used: mediaCategories (in media/media-categories.mdx); title, subtitle, seoDescription, image, imageAlt, shownText (in media/media-title.mdx)

Files: media/media-title.mdx — edited in the CMS via the Media — page header + SEO singleton. media/media-categories.mdx — edited via the Media categories singleton.


Category Descriptions (Projects)

Each project category can have its own introductory text, shown on the Projects page below the category heading. The heading itself is derived automatically from the category enum label (via getCategoryLabel in src/utils/i18n.ts), so it does not need to be set here.

---
title: "Experimental Rocketry"
description: "From design to launch — building and testing real sounding rockets, hybrid engines, and recovery systems."
---

Where it appears: The Projects page category filter section, as a short description under each category heading. The title is required by the schema but not displayed — the visible heading is derived from the category enum label.

Fields used: title (required, not displayed), description

Files: projects/category-experimental-rocketry, projects/category-science-and-experiments, projects/category-robotics


Tips

  • title is required. Every page-text file must have a title field. All other fields are optional — the component will skip missing fields or use a sensible default.
  • buttonText and buttonHref go together. If you provide one without the other, the build will fail with a validation error. The same applies to secondButtonText and secondButtonHref for the optional secondary button.
  • seoDescription matters for search engines. Keep it around 150 characters. It appears in Google search results and social media previews. Only page header files (the -title files) typically need this field.
  • FAQ answers support Markdown. Use **bold**, [link text](/path), and - bullet items to format answers.
  • The {year} placeholder in the copyright text is the only dynamic template supported. It is replaced with the current year at build time.
  • To find which file controls a section, look at the page’s subfolder. For example, all About Us content is in about-us/, all footer content is in footer/.
  • Adding or removing CTA cards on the hero automatically adjusts the grid layout (1–4 columns). You can also set ctas to an empty list to show no cards.
  • All href values must be locale-neutral — always write paths without a /de/ prefix (e.g., /projects, /about-us#find-us-section). The website automatically adds the correct locale prefix when rendering the German version. This applies to buttonHref, secondButtonHref, ctas[].href, navLinks[].href, and navColumns links. Writing /de/projects would result in a broken double-prefix (/de/de/projects).