Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ target/
.idea

.env
doc_build
migration-screenshots
54 changes: 24 additions & 30 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
This is a Zephyr Cloud website built with:

- React 19.1.0
- Rsbuild (Rspack-based build tool)
- Rspress 2.0.5 (SSG docs/site framework)
- TypeScript 5.8.3
- Tailwind CSS 4.1.10
- Shadcn UI components
- TanStack Router for file-based routing
- Rspress routing with MDX pages and generated static blog/changelog routes
- MDX for blog content with frontmatter support
- Zephyr Cloud integration via zephyr-rspack-plugin

## Essential Commands

Expand All @@ -32,10 +31,10 @@ pnpm preview # Preview production build locally

### Build System

- Uses **Rsbuild** (not webpack/vite) configured in `rsbuild.config.ts`
- Integrates with Zephyr Cloud for deployment via custom plugin
- Uses **Rspress** configured in `rspress.config.ts`
- SSG blog/changelog wrappers and metadata generated by `scripts/generate-rspress-content.mjs`
- Uses `@rspress/plugin-sitemap` for sitemap generation
- PostCSS setup with Tailwind CSS v4 plugin architecture
- TanStack Router plugin for automatic route generation

### Directory Structure

Expand All @@ -51,7 +50,6 @@ src/
│ ├── blogPosts.ts # Blog posts data
│ └── companyLogos.ts # Company logos imports
├── routes/ # File-based routes
│ ├── __root.tsx # Root layout
│ ├── index.tsx # Home page
│ ├── privacy.tsx # Privacy policy page
│ └── blog/
Expand All @@ -77,26 +75,21 @@ src/
│ ├── zephyr-logo.svg
│ └── zephyr-wordmark.svg
├── lib/utils.ts # Utility functions (cn for className merging)
├── router.tsx # Router configuration
├── routeTree.gen.ts # Auto-generated route tree (DO NOT EDIT)
├── testimonials.ts # Testimonials data
├── App.css # Global styles with Tailwind imports
├── index.css # Base styles import
└── index.tsx # Entry point with RouterProvider
└── index.css # Base styles import
```

### Routing System

- Uses **TanStack Router** with file-based routing
- Routes are defined in `src/routes/` directory
- `__root.tsx` provides the layout wrapper with Header and Footer
- Auto-generates type-safe route tree
- Internal navigation uses `Link` component from `@tanstack/react-router`
- Uses **Rspress** file-based pages from `docs/`
- Shared layout and head handling live in `theme/index.tsx`
- Blog/changelog detail pages are generated statically into `docs/blog/*.mdx` and `docs/changelog/*.mdx`
- Some legacy page components from `src/routes/` are rendered via `RouteRenderer` in docs pages
- External links use standard `<a>` tags with `target="_blank"`

### Path Aliases

- `@/*` maps to `./src/*` (configured in both tsconfig.json and rsbuild.config.ts)
- `@/*` maps to `./src/*` (configured in tsconfig.json and `rspress.config.ts`)

### Styling System

Expand Down Expand Up @@ -164,7 +157,7 @@ This project uses **pnpm**. Always use pnpm commands, not npm or yarn.
- Target: ES2020
- Module resolution: bundler
- JSX: react-jsx
- Includes generated route types from TanStack Router
- Uses strict TypeScript with bundler module resolution

### Component Organization

Expand All @@ -176,8 +169,8 @@ This project uses **pnpm**. Always use pnpm commands, not npm or yarn.
### Current State

- Production-ready component architecture
- TanStack Router implemented for navigation
- Blog system with MDX support and dynamic routing
- Rspress-based static site with MDX content
- Blog/changelog system rendered as static pages for SEO
- Responsive design with mobile-first approach
- No state management library (using React hooks)
- No testing framework configured
Expand All @@ -195,24 +188,25 @@ This project uses **pnpm**. Always use pnpm commands, not npm or yarn.

### Zephyr Cloud Integration

The project uses zephyr-rspack-plugin for building and deploying to Zephyr Cloud. Production builds automatically generate preview URLs.
The website is built with Rspress SSG and deployed through the Zephyr Cloud website workflow.

### Important Files

- `rsbuild.config.ts` - Build configuration with router plugin
- `src/routes/__root.tsx` - Main layout wrapper
- `rspress.config.ts` - Rspress configuration (aliases, route settings, sitemap)
- `scripts/generate-rspress-content.mjs` - Generates static blog/changelog wrappers and metadata
- `theme/index.tsx` - Site layout wrapper and head integration
- `src/components/sections/Header.tsx` - Navigation with dropdown menus
- `.vscode/settings.json` - Excludes generated files from editing

### Adding New Routes

To add a new route, create a file in `src/routes/`:
To add a new route, create a file in `docs/`:

- `src/routes/about.tsx` → `/about`
- `src/routes/blog/index.tsx` → `/blog`
- `src/routes/blog/$slug.tsx` → `/blog/:slug` (dynamic route)
- `docs/about.mdx` → `/about`
- `docs/blog/index.mdx` → `/blog`
- `docs/changelog/index.mdx` → `/changelog`

The route tree will be automatically regenerated when the dev server is running.
For blog/changelog detail pages sourced from content, update `src/content/blog/*.mdx` or `src/content/changelog/*.mdx` and run `pnpm run generate:rspress-content`.

### Embedding Media in MDX Blog Posts

Expand Down Expand Up @@ -252,7 +246,7 @@ import demoVideo from '@/images/blog/post-name/demo.webm';
</div>
```

Note: All media files (images, videos) should be placed in the blog post's image directory and imported as modules, not referenced as static paths. This ensures proper bundling and optimization by Rsbuild.
Note: All media files (images, videos) should be placed in the blog post's image directory and imported as modules, not referenced as static paths. This ensures proper bundling and optimization by the Rspress build pipeline.

## Image Processing Guidelines

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Start the development server:
pnpm dev
```

Build the app for Zephyr preview urls:
Build the static site for production:

```bash
pnpm build
Expand Down
68 changes: 68 additions & 0 deletions docs/blog/ai-e2e-testing.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: 'AI e2e testing with Midscene, Puppeteer, and Zephyr Cloud | Zephyr Cloud'
description: 'Exploring AI-powered end-to-end testing with Midscene and how it integrates with Zephyr Cloud deployments'
head:
- - meta
- property: og:type
content: article
- - meta
- property: og:title
content: 'AI e2e testing with Midscene, Puppeteer, and Zephyr Cloud'
- - meta
- property: og:description
content: 'Exploring AI-powered end-to-end testing with Midscene and how it integrates with Zephyr Cloud deployments'
- - meta
- property: og:url
content: 'https://zephyr-cloud.io/blog/ai-e2e-testing'
- - meta
- property: og:image
content: 'https://zephyr-cloud.io/images/blog/ai-e2e-testing/ai-testing-hero.webp'
- - meta
- property: og:image:type
content: 'image/webp'
- - meta
- property: og:image:secure_url
content: 'https://zephyr-cloud.io/images/blog/ai-e2e-testing/ai-testing-hero.webp'
- - meta
- name: twitter:card
content: summary_large_image
- - meta
- name: twitter:title
content: 'AI e2e testing with Midscene, Puppeteer, and Zephyr Cloud'
- - meta
- name: twitter:description
content: 'Exploring AI-powered end-to-end testing with Midscene and how it integrates with Zephyr Cloud deployments'
- - meta
- name: twitter:image
content: 'https://zephyr-cloud.io/images/blog/ai-e2e-testing/ai-testing-hero.webp'
- - meta
- name: twitter:image:type
content: 'image/webp'
- - meta
- name: twitter:image:src
content: 'https://zephyr-cloud.io/images/blog/ai-e2e-testing/ai-testing-hero.webp'
- - link
- rel: canonical
href: 'https://zephyr-cloud.io/blog/ai-e2e-testing'
---

import PostBody from '@/content/blog/ai-e2e-testing.mdx';
import { BlogArticlePage } from '../../src/components/pages/BlogArticlePage';

export const pageMetadata = {
title: 'AI e2e testing with Midscene, Puppeteer, and Zephyr Cloud',
slug: 'ai-e2e-testing',
date: '2025-02-18',
heroImage: '/images/blog/ai-e2e-testing/ai-testing-hero.webp',
listingImage: '/images/blog/ai-e2e-testing/ai-testing-listing.webp',
description:
'Exploring AI-powered end-to-end testing with Midscene and how it integrates with Zephyr Cloud deployments',
authors: ['Zack Chapple'],
tags: ['ai', 'tutorial', 'engineering'],
featured: false,
readingTime: 6,
};

<BlogArticlePage slug={'ai-e2e-testing'} metadata={pageMetadata}>
<PostBody />
</BlogArticlePage>
62 changes: 62 additions & 0 deletions docs/blog/all-the-pipelines.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
title: 'One Build. Many Clouds. Zero Headaches. | Zephyr Cloud'
description: 'Multi-CDN deployments in Zephyr Cloud - push the same build to multiple cloud providers and domains in a single, seamless flow'
head:
- - meta
- property: og:type
content: article
- - meta
- property: og:title
content: 'One Build. Many Clouds. Zero Headaches.'
- - meta
- property: og:description
content: 'Multi-CDN deployments in Zephyr Cloud - push the same build to multiple cloud providers and domains in a single, seamless flow'
- - meta
- property: og:url
content: 'https://zephyr-cloud.io/blog/all-the-pipelines'
- - meta
- property: og:image
content: 'https://zephyr-cloud.io/images/blog/all-the-pipelines/hero.svg'
- - meta
- property: og:image:secure_url
content: 'https://zephyr-cloud.io/images/blog/all-the-pipelines/hero.svg'
- - meta
- name: twitter:card
content: summary_large_image
- - meta
- name: twitter:title
content: 'One Build. Many Clouds. Zero Headaches.'
- - meta
- name: twitter:description
content: 'Multi-CDN deployments in Zephyr Cloud - push the same build to multiple cloud providers and domains in a single, seamless flow'
- - meta
- name: twitter:image
content: 'https://zephyr-cloud.io/images/blog/all-the-pipelines/hero.svg'
- - meta
- name: twitter:image:src
content: 'https://zephyr-cloud.io/images/blog/all-the-pipelines/hero.svg'
- - link
- rel: canonical
href: 'https://zephyr-cloud.io/blog/all-the-pipelines'
---

import PostBody from '@/content/blog/all-the-pipelines.mdx';
import { BlogArticlePage } from '../../src/components/pages/BlogArticlePage';

export const pageMetadata = {
title: 'One Build. Many Clouds. Zero Headaches.',
slug: 'all-the-pipelines',
date: '2025-04-24',
heroImage: '/images/blog/all-the-pipelines/hero.svg',
listingImage: '/images/blog/all-the-pipelines/hero.svg',
description:
'Multi-CDN deployments in Zephyr Cloud - push the same build to multiple cloud providers and domains in a single, seamless flow',
authors: ['Rodrigo Yokota'],
tags: ['cloud', 'devops', 'announcement'],
featured: false,
readingTime: 5,
};

<BlogArticlePage slug={'all-the-pipelines'} metadata={pageMetadata}>
<PostBody />
</BlogArticlePage>
67 changes: 67 additions & 0 deletions docs/blog/aws-byoc.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: 'Zephyr Cloud + AWS: A New Milestone for Bring Your Own Cloud | Zephyr Cloud'
description: "In today's fast-moving digital world, choosing the right cloud is about more than cost—it's about control, flexibility, and the freedom to innovate without being locked in. At Zephyr, we've always believed that your cloud strategy should be your strategy, not something dictated by vendors or technical limitations."
head:
- - meta
- property: og:type
content: article
- - meta
- property: og:title
content: 'Zephyr Cloud + AWS: A New Milestone for Bring Your Own Cloud'
- - meta
- property: og:description
content: "In today's fast-moving digital world, choosing the right cloud is about more than cost—it's about control, flexibility, and the freedom to innovate without being locked in. At Zephyr, we've always believed that your cloud strategy should be your strategy, not something dictated by vendors or technical limitations."
- - meta
- property: og:url
content: 'https://zephyr-cloud.io/blog/aws-byoc'
- - meta
- property: og:image
content: 'https://zephyr-cloud.io/images/blog/aws-byoc/blog-post-aws.webp'
- - meta
- property: og:image:type
content: 'image/webp'
- - meta
- property: og:image:secure_url
content: 'https://zephyr-cloud.io/images/blog/aws-byoc/blog-post-aws.webp'
- - meta
- name: twitter:card
content: summary_large_image
- - meta
- name: twitter:title
content: 'Zephyr Cloud + AWS: A New Milestone for Bring Your Own Cloud'
- - meta
- name: twitter:description
content: "In today's fast-moving digital world, choosing the right cloud is about more than cost—it's about control, flexibility, and the freedom to innovate without being locked in. At Zephyr, we've always believed that your cloud strategy should be your strategy, not something dictated by vendors or technical limitations."
- - meta
- name: twitter:image
content: 'https://zephyr-cloud.io/images/blog/aws-byoc/blog-post-aws.webp'
- - meta
- name: twitter:image:type
content: 'image/webp'
- - meta
- name: twitter:image:src
content: 'https://zephyr-cloud.io/images/blog/aws-byoc/blog-post-aws.webp'
- - link
- rel: canonical
href: 'https://zephyr-cloud.io/blog/aws-byoc'
---

import PostBody from '@/content/blog/aws-byoc.mdx';
import { BlogArticlePage } from '../../src/components/pages/BlogArticlePage';

export const pageMetadata = {
title: 'Zephyr Cloud + AWS: A New Milestone for Bring Your Own Cloud',
slug: 'aws-byoc',
date: '2025-08-25',
heroImage: '/images/blog/aws-byoc/blog-post-aws.webp',
listingImage: '/images/blog/aws-byoc/blog-post-aws.webp',
description:
"In today's fast-moving digital world, choosing the right cloud is about more than cost—it's about control, flexibility, and the freedom to innovate without being locked in. At Zephyr, we've always believed that your cloud strategy should be your strategy, not something dictated by vendors or technical limitations.",
authors: [],
tags: ['cloud', 'announcement'],
featured: false,
};

<BlogArticlePage slug={'aws-byoc'} metadata={pageMetadata}>
<PostBody />
</BlogArticlePage>
Loading
Loading