A community-driven learning course and resource hub for FRC Design and CAD, using Onshape. Built with Astro and Starlight.
.
├── public/ # Static assets (favicon)
├── src/
│ ├── assets/
│ │ ├── content/ # Optimized images for documentation
│ │ ├── footer/ # Footer assets
│ │ ├── header/ # Header assets
│ │ ├── home/ # Homepage assets
│ │ └── universal/ # Shared assets
│ ├── components/ # Custom Astro components
│ │ ├── Aside.astro # Styled callout boxes (note, tip, caution, danger, example)
│ │ ├── Countdown.astro # Countdown timer component
│ │ ├── Glossary.astro # Glossary term definitions
│ │ ├── HomeCard.astro # Homepage card component
│ │ ├── LinkButton.astro # Styled link buttons
│ │ ├── Slides.astro # Image/video slideshow with lightbox
│ │ └── YouTube.astro # YouTube video embeds
│ ├── config/ # Sidebar configuration
│ ├── content/
│ │ └── docs/ # MDX documentation pages
│ ├── data/ # Static data files
│ ├── plugins/ # Remark/Rehype plugins (center, figure, glossary, image-attributes)
│ ├── starlightOverrides/ # Custom Starlight component overrides
│ │ ├── Footer.astro # Custom footer
│ │ ├── Header.astro # Custom header with navigation
│ │ ├── Hero.astro # Custom hero component
│ │ ├── Pagination.astro # Custom pagination
│ │ └── Sidebar.astro # Custom sidebar
│ └── styles/ # Global styles
├── astro.config.mjs # Astro configuration
├── package.json
└── tsconfig.json
Styled callout boxes with optional collapse functionality.
import Aside from '@components/Aside.astro';
<Aside type="tip">This is a tip!</Aside>
<Aside type="note" title="Custom Title">Content here</Aside>
<Aside type="caution" collapse>Collapsible content</Aside>Types: note, tip, caution, danger, example
Image and video slideshow with lightbox support. Images are automatically optimized when placed in src/assets/content/.
Format: Each slide is an image immediately followed by its caption:
import Slides from '@components/Slides.astro';
<Slides>

Caption for slide 1

Caption for slide 2

Caption for YouTube video
</Slides>With custom scale (0.1 to 1, default is 0.8):
<Slides scale={0.6}>

A smaller slideshow at 60% width
</Slides>Props:
scale: Controls the width of the slideshow (default:0.8= 80% width)
Supported media types:
- Images (
.webp,.png,.jpg,.jpeg) - automatically optimized - YouTube videos (watch URLs, embed URLs, or short URLs) - displayed at 16:9
- Video files (
.webm,.mp4)
YouTube video embed with optional caption.
import YouTube from '@components/YouTube.astro';
<YouTube id="VIDEO_ID" />
<YouTube url="https://www.youtube.com/watch?v=VIDEO_ID">
Optional caption with **markdown** support
</YouTube>Styled button link component.
import LinkButton from '@components/LinkButton.astro';
<LinkButton href="/path">Button Text</LinkButton>
<LinkButton href="/path" center>Centered Button</LinkButton>
<LinkButton href="/path" blank={false}>Internal Link (no new tab)</LinkButton>Props:
href(required): Link URLcenter: Centers the button (default:false)blank: Opens in new tab (default:true)
Use the :::center block directive to center text content:
:::center
**Centered text with markdown**
:::This works with any content including text, images, videos, or other elements. The directive uses the remark-directive syntax (already included in Starlight).
Cards with styling custom for the website. Can be used with CardGrid
import CustomCard from '@components/CustomCard.astro';
<CustomCard title="Visible title" subTitle="Italicized unlinked text next to title" href="hyperlink for the title">
Any markdown text, images, components or styling.
</CustomCard>
<CustomCard title="Visible title" subTitle="Italicized unlinked text next to title" href="hyperlink for the title" />Props:
title: Bold card titlesubTitle: Italicized text next to the titlehref: Link to make the title text a hyperlink
Use it with CardGrid as follows:
import { CardGrid } from '@astrojs/starlight/components';
import CustomCard from '@components/CustomCard.astro';
<CardGrid>
<CustomCard title="Visible title" subTitle="Italicized unlinked text next to title" href="hyperlink for the title">
Any markdown text, images, components or styling.
</CustomCard>
<CustomCard title="Visible title" subTitle="Italicized unlinked text next to title" href="hyperlink for the title">
Any markdown text, images, components or styling.
</CustomCard>
</CardGrid>Use the :::figure block directive for creating semantic figures with captions:
:::figure

Caption text here
:::With custom width (percentage of container):
:::figure{w=70}

Caption text here (at 70% width)
:::With border:
:::figure{border}

Caption with default border
:::With both width and border:
:::figure{w=60 border}

Caption at 60% width with border
:::Attributes:
w: Width as a percentage (e.g.,w=70for 70% width). Omit for 100% width.border: Adds a gray border around the image
The figure directive:
- Centers the image and caption automatically
- Renders as semantic
<figure>and<figcaption>HTML elements - Supports markdown formatting in captions (links, bold, etc.)
- Images are automatically optimized when using relative paths
Standard markdown images work and are automatically centered:
Add width, alignment, and border to images using URL hash syntax:
Width (percentage of container):
Alignment (left, center, right - default is center):

Border (adds a gray border):
Combine multiple attributes with &:
Attributes:
w: Width as a percentage (e.g.,w=60for 60% width)align: Alignment (left,center,right). Default iscenter.border: Adds default border (5px solid gray), or specify custom:border=2px_solid_red(use underscores for spaces)
Place images in src/assets/content/ for automatic optimization. The path should match the folder structure without the src/assets/content prefix:
- File location:
src/assets/content/learning-course/stage1/image.webp - Component path:
src="/learning-course/stage1/image.webp"
For multiple images, use the Slides component instead.
- Custom Header: Green branded header with navigation tabs, search, and theme toggle
- Theme Switching: Light/dark mode with persistent preference
- Image Optimization: Automatic image optimization for images in
src/assets/content/ - Image Lightbox: Click any image to view full-screen with keyboard navigation and captions
- Glossary System: Automatic tooltip definitions for technical terms
- Responsive Design: Mobile-friendly with unified hamburger menu navigation
- Node.js (version 18 or higher): Download from nodejs.org
- Git: Download from git-scm.com
- A code editor (e.g., VS Code)
-
Clone the repository
git clone https://github.com/frcdesign/FRCDesign.org.git cd FRCDesign.org -
Install dependencies
npm install
-
Start the development server
npm run dev
-
Open in browser
Visit http://localhost:4321 to see the site running locally.
-
Make changes
Edit files in
src/content/docs/to modify content. The browser will automatically reload when you save changes.
To check your Node.js and npm versions:
node --version # Should be 18.x or higher
npm --version # Should be 9.x or higher| Command | Action |
|---|---|
npm install |
Install dependencies |
npm run dev |
Start local dev server at localhost:4321 |
npm run build |
Build production site to ./dist/ |
npm run preview |
Preview build locally before deploying |
This site is configured for deployment on Cloudflare Pages using the @astrojs/cloudflare adapter.
See the Contribution Guide on the website for details on how to contribute to FRCDesign.org.