The tech blog and documentation site for QVeris AI, built with Astro. Designed to be embedded as an iframe within qveris.ai and qveris.cn, while also working as a standalone site.
- Framework: Astro 6 + MDX
- Language: TypeScript
- Styling: CSS custom properties (QVeris Visual System)
- Fonts: Plus Jakarta Sans + JetBrains Mono
- Package Manager: pnpm
src/
├── assets/ # Images (optimized via Sharp at build time)
├── components/ # Astro components
│ ├── Nav.astro # Sticky nav with backdrop blur & lang switcher
│ ├── BlogHero.astro # Landing page hero section
│ ├── PostCard.astro # Blog post card with hover effects
│ ├── TableOfContents.astro # Sticky sidebar TOC
│ ├── PostMeta.astro # Date + reading time + category
│ ├── Breadcrumb.astro # Path breadcrumb
│ ├── Callout.astro # Tip/warning/info boxes for MDX
│ ├── Eyebrow.astro # Mono uppercase label
│ ├── Divider.astro # Gradient divider
│ ├── ScrollReveal.astro # Scroll-triggered animation wrapper
│ └── ...
├── content/
│ ├── blog/
│ │ ├── en/ # English blog posts
│ │ └── cn/ # Chinese blog posts
│ └── doc/
│ ├── en/ # English docs
│ └── cn/ # Chinese docs
├── i18n/ # Locale config, labels, and utilities
├── layouts/
│ ├── BaseLayout.astro # Root layout (nav + scripts)
│ ├── BlogPost.astro # 2-column: content + TOC sidebar
│ └── DocPage.astro # Doc layout with optional TOC
├── pages/ # File-based routing
├── scripts/ # Client-side JS (scroll-reveal, TOC highlight, code copy)
├── styles/
│ ├── global.css # QVeris Visual System tokens + base styles
│ └── prose.css # Rich article content styling
└── utils/ # Reading time calculator, etc.
- Full QVeris Visual System implementation (dark theme, design tokens, 3-layer shadow system)
- Blog landing with hero section, featured post, and responsive card grid
- Blog posts with 2-column layout (prose content + sticky Table of Contents sidebar)
- Scroll-reveal animations with
prefers-reduced-motionsupport - Code blocks with copy-to-clipboard buttons
- Global (qveris.ai): English default, Chinese available, language switcher visible
- China (qveris.cn): Chinese only, language switcher hidden
- Region set via
?region=cn|globalquery parameter
- Designed for iframe embedding within qveris.ai / qveris.cn
?embed=trueactivates compact nav modepostMessageAPI for parent-frame communication:{ type: 'qveris:set-locale', locale: 'en' | 'cn' }{ type: 'qveris:set-region', region: 'cn' | 'global' }
window.__QVERIS_EMBED__JS API:setLocale(),setRegion(),getRegion()
- MDX support with custom components (Callout, etc.)
- Content schema:
title,description,pubDate,heroImage,category,author,tags,featured,draft,translationKey - Bilingual content linked via
translationKey - Draft filtering in production builds and RSS feed
| Command | Description |
|---|---|
pnpm install |
Install dependencies |
pnpm dev |
Local dev server (default port 4321) |
pnpm build |
Production build to ./dist/ |
pnpm preview |
Preview the production build locally |
pnpm blog:manifest |
Regenerate the committed blog metadata manifests |
- Create
src/content/blog/en/your-post-slug.md(and optionallycn/for Chinese) - Add frontmatter:
--- title: 'Post Title' description: 'Brief description' pubDate: 'Apr 07 2026' heroImage: '../../../assets/your-hero.png' category: 'Engineering' author: 'QVeris Team' tags: ['agents', 'infrastructure'] featured: false draft: false translationKey: 'your-post-slug' ---
- Write content in Markdown/MDX
- Run
pnpm blog:manifestand commit both locale manifests - Run
pnpm buildto verify
The committed src/content/blog/en/posts.json and
src/content/blog/cn/posts.json files are the metadata indexes consumed by the
QVeris website. The production build fails when either file is missing or stale,
so every content change must include the regenerated manifests.
Deployed to GitHub Pages via GitHub Actions on push to main. See .github/workflows/deploy.yml.
See LICENSE.