mirror of
https://github.com/zoriya/v10.git
synced 2026-08-15 02:14:06 +00:00
352 lines
11 KiB
Markdown
352 lines
11 KiB
Markdown
## 🚀 Project Structure
|
|
|
|
Inside of your Astro project, you'll see the following folders and files:
|
|
|
|
```text
|
|
├── public/
|
|
├── src/
|
|
│ ├── components/
|
|
│ ├── content/
|
|
│ ├── layouts/
|
|
│ └── pages/
|
|
├── astro.config.mjs
|
|
├── README.md
|
|
├── package.json
|
|
└── tsconfig.json
|
|
```
|
|
|
|
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
|
|
|
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
|
|
|
The `src/content/` directory contains "collections" of related Markdown and MDX documents. Use `getCollection()` to retrieve posts from `src/content/blog/`, and type-check your frontmatter using an optional schema. See [Astro's Content Collections docs](https://docs.astro.build/en/guides/content-collections/) to learn more.
|
|
|
|
Any static assets, like images, can be placed in the `public/` directory.
|
|
|
|
## 🧞 Commands
|
|
|
|
All commands are run from the root of the project, from a terminal:
|
|
|
|
| Command | Action |
|
|
| :--------------------- | :----------------------------------------------- |
|
|
| `pnpm install` | Installs dependencies |
|
|
| `pnpm dev` | Starts local dev server at `localhost:4321` |
|
|
| `pnpm build` | Build your production site to `./dist/` |
|
|
| `pnpm preview` | Preview your build locally, before deploying |
|
|
| `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` |
|
|
| `pnpm astro -- --help` | Get help using the Astro CLI |
|
|
|
|
## 🚀 Project architecture
|
|
|
|
### Overview
|
|
|
|
The website serves two main purposes:
|
|
|
|
1. **Blog** - News, updates, and announcements about Video.js
|
|
2. **Documentation** - Multi-framework documentation system with conditional content
|
|
|
|
### Project Structure
|
|
|
|
```text
|
|
website/
|
|
├── src/
|
|
│ ├── components/ # Reusable UI components
|
|
│ │ └── docs/ # Documentation-specific components
|
|
│ ├── config/ # Configuration files
|
|
│ │ └── docs/ # Documentation sidebar configuration
|
|
│ ├── content/ # Content collections (blog, docs)
|
|
│ │ ├── blog/ # Blog posts (Markdown/MDX)
|
|
│ │ └── docs/ # Documentation pages (MDX)
|
|
│ ├── layouts/ # Page layouts
|
|
│ ├── pages/ # Route definitions
|
|
│ ├── styles/ # Global styles
|
|
│ ├── types/ # TypeScript type definitions
|
|
│ ├── utils/ # Utility functions
|
|
│ └── consts.ts # Site-wide constants
|
|
├── public/ # Static assets (fonts, favicon, images)
|
|
└── astro.config.mjs # Astro configuration
|
|
```
|
|
|
|
### Key Features
|
|
|
|
#### 1. Blog System
|
|
|
|
The blog uses Astro's Content Collections API with a custom loader for automatic metadata extraction.
|
|
|
|
##### Filename Convention
|
|
|
|
Blog posts use date-prefixed filenames: `YYYY-MM-DD-slug.{md,mdx}`
|
|
|
|
Example: `2024-01-15-new-release.md`
|
|
|
|
##### Automatic Metadata
|
|
|
|
- **Publication date** is extracted from the filename
|
|
- **Updated date** is pulled from git history (last commit that modified the file)
|
|
- **URL slug** has the date prefix removed for clean URLs (`/blog/new-release/`)
|
|
|
|
##### Implementation
|
|
|
|
See [content.config.ts](src/content.config.ts) for the blog collection definition and [utils/globWithParser.ts](src/utils/globWithParser.ts) for the custom loader implementation.
|
|
|
|
#### 2. Multi-Framework Documentation System
|
|
|
|
The most sophisticated part of the website is the documentation system, which adapts content based on:
|
|
|
|
- **Framework** (HTML, React)
|
|
- **Styling approach** (CSS, Tailwind)
|
|
|
|
##### URL Structure
|
|
|
|
```text
|
|
/docs/framework/{framework}/style/{style}/{slug}/
|
|
```
|
|
|
|
Example: `/docs/framework/react/style/tailwind/concepts/state-management/`
|
|
|
|
##### Framework/Style Matrix
|
|
|
|
| Framework | Available Styles |
|
|
| --------- | ---------------- |
|
|
| HTML | css, tailwind |
|
|
| React | css, tailwind |
|
|
|
|
##### Content Filtering
|
|
|
|
Documentation pages can be restricted to specific frameworks or styles:
|
|
|
|
**In sidebar config** ([config/docs/sidebar.ts](src/config/docs/sidebar.ts)):
|
|
|
|
```ts
|
|
const sidebar = {
|
|
title: 'React Concepts',
|
|
guides: [
|
|
{ slug: 'concepts/hooks' }, // Available to all
|
|
{
|
|
slug: 'concepts/styling',
|
|
frameworks: ['react'], // Only for React
|
|
styles: ['styled-components'] // Only for styled-components
|
|
}
|
|
]
|
|
};
|
|
```
|
|
|
|
**Within MDX content** (using conditional components):
|
|
|
|
```mdx
|
|
<FrameworkCase frameworks={['react']}>This content only appears in React docs.</FrameworkCase>
|
|
|
|
<StyleCase styles={['tailwind']}>This content only appears when Tailwind is selected.</StyleCase>
|
|
```
|
|
|
|
##### Static Site Generation
|
|
|
|
The docs system generates all valid framework/style/slug combinations at build time:
|
|
|
|
1. Filter sidebar based on framework/style
|
|
2. Generate pages only for guides visible in that combination
|
|
3. Each page is pre-rendered with the appropriate filtered sidebar
|
|
|
|
See [pages/docs/framework/[framework]/style/[style]/[...slug].astro](src/pages/docs/framework/[framework]/style/[style]/[...slug].astro) for implementation.
|
|
|
|
##### Smart Navigation
|
|
|
|
The framework/style selectors ([components/docs/Selectors.tsx](src/components/docs/Selectors.tsx)) attempt to preserve the current guide when switching:
|
|
|
|
1. User switches from "React" to "HTML"
|
|
2. System checks if current guide supports HTML
|
|
3. If yes: Navigate to same guide with HTML/best-style
|
|
4. If no: Navigate to first available guide for HTML
|
|
|
|
This creates a seamless experience where users don't lose their place when switching contexts.
|
|
|
|
### Custom Utilities
|
|
|
|
#### globWithParser ([utils/globWithParser.ts](src/utils/globWithParser.ts))
|
|
|
|
Wraps Astro's `glob` loader to provide access to both transformed entry IDs and original filenames. This is essential for extracting dates from date-prefixed blog post filenames while maintaining clean URLs.
|
|
|
|
**How it works:**
|
|
|
|
1. Wraps the `generateId` function to capture ID transformations
|
|
2. Stores mapping: `transformed ID → original filename`
|
|
3. Injects custom parser that receives both values
|
|
4. Parser adds metadata to entry before schema validation
|
|
|
|
**Why it's needed:**
|
|
|
|
- `generateId` transforms: `2024-01-15-post.md` → `post`
|
|
- Parser needs access to `2024-01-15-post.md` to extract the date
|
|
- Without this utility, the original filename is lost after transformation
|
|
|
|
### Content Collections
|
|
|
|
#### Blog Collection
|
|
|
|
- **Location**: `src/content/blog/`
|
|
- **Formats**: Markdown (`.md`) and MDX (`.mdx`)
|
|
- **Required frontmatter**: `title`, `description`
|
|
- **Auto-injected**: `pubDate` (from filename), `updatedDate` (from git)
|
|
|
|
#### Docs Collection
|
|
|
|
- **Location**: `src/content/docs/`
|
|
- **Formats**: MDX only (needs conditional components)
|
|
- **Required frontmatter**: `title`, `description`
|
|
- **Auto-injected**: `updatedDate` (from git)
|
|
- **Visibility**: Controlled by sidebar configuration
|
|
|
|
### Layouts
|
|
|
|
#### Base Layout
|
|
|
|
Base HTML structure with:
|
|
|
|
- SEO meta tags (Open Graph, Twitter Cards)
|
|
- Font preloading
|
|
- Client-side routing (Astro Transitions)
|
|
|
|
#### BlogPost Layout
|
|
|
|
Extends Base with blog-specific elements:
|
|
|
|
- Hero image display
|
|
- Publication and updated dates
|
|
- Article formatting
|
|
|
|
#### Docs Layout
|
|
|
|
Extends Base with documentation features:
|
|
|
|
- Filtered sidebar navigation
|
|
- Framework/style selectors (React component with client-side routing)
|
|
- Two-column layout (sidebar + content)
|
|
|
|
### Configuration
|
|
|
|
#### Site Configuration
|
|
|
|
[astro.config.mjs](astro.config.mjs) includes:
|
|
|
|
- MDX integration for rich content authoring
|
|
- React integration for interactive components (selectors)
|
|
- Sitemap generation
|
|
- RSS feed generation
|
|
- Tailwind CSS via Vite plugin
|
|
|
|
### Sidebar Configuration
|
|
|
|
[config/docs/sidebar.ts](src/config/docs/sidebar.ts) defines the documentation structure:
|
|
|
|
- Hierarchical sections and subsections
|
|
- Guide definitions with framework/style restrictions
|
|
- Custom sidebar labels (overrides doc titles)
|
|
|
|
### Type System
|
|
|
|
The documentation system is fully typed in TypeScript:
|
|
|
|
- `SupportedFramework` - Union type of available frameworks
|
|
- `SupportedStyle<F>` - Style type specific to a framework
|
|
- `Guide` - Guide definition with optional restrictions
|
|
- `Section` - Recursive type for sidebar sections
|
|
- `Sidebar` - Array of top-level sections
|
|
|
|
See [types/docs.ts](src/types/docs.ts) for complete type definitions.
|
|
|
|
### Development Workflow
|
|
|
|
#### Adding a Blog Post
|
|
|
|
1. Create file: `src/content/blog/YYYY-MM-DD-slug.md`
|
|
2. Add frontmatter: `title`, `description`
|
|
3. Write content in Markdown or MDX
|
|
4. The `pubDate` is automatically extracted from filename
|
|
5. The `updatedDate` is automatically pulled from git on subsequent commits
|
|
|
|
#### Adding a Documentation Page
|
|
|
|
1. Create file: `src/content/docs/category/page-name.mdx`
|
|
2. Add frontmatter: `title`, `description`
|
|
3. Add to sidebar in `src/config/docs/sidebar.ts`:
|
|
|
|
```ts
|
|
const sidebar = {
|
|
title: 'Category',
|
|
guides: [
|
|
{
|
|
slug: 'category/page-name',
|
|
frameworks: ['react'], // optional
|
|
styles: ['tailwind', 'css'] // optional
|
|
}
|
|
]
|
|
};
|
|
```
|
|
|
|
4. Use conditional components for framework/style-specific content
|
|
|
|
#### Adding a New Framework
|
|
|
|
1. Update `FRAMEWORK_STYLES` in [types/docs.ts](src/types/docs.ts)
|
|
2. Add available styles for the framework
|
|
3. Update documentation to include framework-specific guides
|
|
4. The system will automatically generate all URL combinations
|
|
|
|
#### Adding a New Style
|
|
|
|
1. Update `FRAMEWORK_STYLES` in [types/docs.ts](src/types/docs.ts)
|
|
2. Add the style to appropriate framework(s)
|
|
3. Update documentation guides to support the new style
|
|
4. The system will automatically generate all URL combinations
|
|
|
|
### Build Output
|
|
|
|
The site is statically generated with:
|
|
|
|
- Pre-rendered HTML for all pages
|
|
- Client-side routing for SPA-like navigation
|
|
- Optimized images via Astro's image optimization
|
|
- Sitemap at `/sitemap-index.xml`
|
|
- RSS feed at `/rss.xml`
|
|
|
|
### Dependencies
|
|
|
|
#### Core Framework
|
|
|
|
- **Astro** - Static site generator with island architecture
|
|
- **React** - For interactive components (framework/style selectors)
|
|
- **TypeScript** - Type safety throughout
|
|
|
|
#### Content Processing
|
|
|
|
- **@astrojs/mdx** - MDX support for rich content
|
|
- **@astrojs/rss** - RSS feed generation
|
|
- **@astrojs/sitemap** - Sitemap generation
|
|
|
|
#### Styling
|
|
|
|
- **Tailwind CSS** - Via @tailwindcss/vite plugin
|
|
- **@astrojs/react** - React component support
|
|
|
|
#### Git Integration
|
|
|
|
- **simple-git** - For extracting file modification dates from git history
|
|
|
|
### Performance Considerations
|
|
|
|
- All pages are pre-rendered at build time
|
|
- Client-side routing eliminates full page reloads
|
|
- Images are optimized with Astro's built-in image optimization
|
|
- Fonts are preloaded to prevent layout shift
|
|
- Minimal JavaScript (only for interactive selectors)
|
|
|
|
### Future Enhancements
|
|
|
|
Areas for potential improvement:
|
|
|
|
- Add search functionality
|
|
- Implement active link highlighting in sidebar
|
|
- Create custom 404 page with framework/style context
|
|
- Add automated testing for sidebar filtering logic
|
|
- Consider server-side rendering for dynamic content
|