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.
| Field | Type | Description |
|---|---|---|
title | string (required) | Section heading |
subtitle | string | Secondary heading, label, or tagline displayed above or below the title |
description | string | Paragraph text (intro copy, explanations) |
seoDescription | string | Meta description for search engines (~150 characters) |
buttonText | string | Primary button label (pair with buttonHref) |
buttonHref | string | Primary button link URL (pair with buttonText) |
secondButtonText | string | Secondary button label (pair with secondButtonHref) |
secondButtonHref | string | Secondary button link URL (pair with secondButtonText) |
instagramButtonText | string | Label for the “Follow us on Instagram” button |
ctas | array | Call-to-action cards (max 4), each with title, description, href |
items | array | List of strings (for addresses, benefits, tiers — see below) |
faqs | array | FAQ entries, each with question and answer (answers support Markdown) |
socialLinks | array | Social media links, each with platform (id of an entry in the Social platforms collection), url, optional hoverColor override |
navLinks | array | Simple navigation links, each with label and href |
navColumns | array | Multi-column navigation, each with heading, href, and nested links |
accountHolder | string | Donation: account holder name (donate card) |
bankName | string | Donation: bank name |
iban | string | Donation: IBAN for bank transfers |
bic | string | Donation: BIC / SWIFT code |
reference | string | Donation: suggested transfer reference |
paypalUrl | string | Donation: full PayPal donation URL (pair with paypalButtonText) |
paypalButtonText | string | Donation: PayPal button label (pair with paypalUrl) |
room | string | About Us “Where to find us”: large room/building label |
schedule | string | About Us “Where to find us”: meeting time |
mapLat | number | Latitude of the pin on the About Us “Where to find us” map |
mapLng | number | Longitude of the pin on the About Us “Where to find us” map |
rememberLabel | string | About Us “Where to find us”: small uppercase label above the room/schedule (e.g. “remember:“) |
emailLabel | string | Contact page: heading on the email card |
addressLabel | string | Contact page: heading on the address card |
mapLinkText | string | Contact page: text on the link below the address that jumps to the map |
followLabel | string | Contact page: heading on the social-links card |
showMoreText | string | Landing page “Latest news”: mobile-only button that expands the list |
showLessText | string | Landing page “Latest news”: mobile-only button that collapses the list |
orDividerText | string | Sponsors page: small uppercase label between the sponsor CTA and the donation block (e.g. “Or”) |
bankToggleText | string | Sponsors 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
Sponsor Tier Descriptions
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- itemfor 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.
Donate Card
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):
- A small heading (uses
title) - A short description (
description) - A row of three value labels with icons (from
items— icons are hardcoded in the page template, labels are editable here) - Two buttons side-by-side: “Donate via PayPal” (primary) and “Bank transfer details” (secondary, expands the bank block)
- 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,bicis present. Each row inside the block is only shown if its field is set. - The PayPal button only renders if both
paypalUrlandpaypalButtonTextare provided — same pairing rule asbuttonText/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.
Social Media Links
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.
Footer Navigation (Multi-Column)
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.
Bottom Bar (Copyright + Legal Links)
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:
| ID | Images from |
|---|---|
all | Combined images from all other listed categories (special) |
about-us | About Us page images (src/assets/about-us/our-mission/) |
events | Event cover images (src/assets/events/) |
people | Person portraits — Faces of BEARS, Meet the Team, and Testimonials (src/assets/people/) |
hero | All hero images across pages (src/assets/hero/) |
projects | Project cover images (src/assets/projects/) |
what-is-bears | What 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
labelto set the displayed title (this is translated per locale). - “All” category: When
allis 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
titleis required. Every page-text file must have atitlefield. All other fields are optional — the component will skip missing fields or use a sensible default.buttonTextandbuttonHrefgo together. If you provide one without the other, the build will fail with a validation error. The same applies tosecondButtonTextandsecondButtonHreffor the optional secondary button.seoDescriptionmatters for search engines. Keep it around 150 characters. It appears in Google search results and social media previews. Only page header files (the-titlefiles) typically need this field.- FAQ answers support Markdown. Use
**bold**,[link text](/path), and- bullet itemsto 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 infooter/. - Adding or removing CTA cards on the hero automatically adjusts the grid layout (1–4 columns). You can also set
ctasto an empty list to show no cards. - All
hrefvalues 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 tobuttonHref,secondButtonHref,ctas[].href,navLinks[].href, andnavColumnslinks. Writing/de/projectswould result in a broken double-prefix (/de/de/projects).