Skip to content

feat(site): add download landing page#992

Merged
Astro-Han merged 10 commits into
devfrom
claude/download-landing
May 30, 2026
Merged

feat(site): add download landing page#992
Astro-Han merged 10 commits into
devfrom
claude/download-landing

Conversation

@Astro-Han

@Astro-Han Astro-Han commented May 30, 2026

Copy link
Copy Markdown
Owner

Summary

Add a standalone download landing page as a new Astro static site under site/.

  • Plain CSS (no UI framework); light/dark + EN/中 toggles; deploys to Cloudflare Pages independently of the desktop app build (site/ lives outside the packages/* workspace).
  • Ported faithfully from the approved design (docs/design/scratch/2026-05-30-download-landing-pawwork-final.html, signed off 2026-05-30).
  • English first paint for basic SEO (title / description / canonical / OG); the client switches to Chinese by browser language or the toggle, persisted in localStorage. An inline anti-flash script sets the theme before first paint.
  • Download buttons point at the GitHub Releases page for now; site/src/config.ts centralizes the links so China-hosted direct links can drop in later.

Why

China-market promotion (Xiaohongshu) is blocked on non-technical users in China downloading from GitHub reliably. This is PR A of the two-part download-distribution plan: PR A = the landing page (this PR); PR B = updater China fallback (#219). Stage 1 hosts installers on Cloudflare R2 behind pawwork.ai, and this page is the front door.

Related Issue

No standalone issue. Tracked as "PR A" of the download-landing / China-promotion plan; the companion updater work is #219.

Human Review Status

Pending

Review Focus

  • Faithfulness to the approved design across the four EN/CN × light/dark combinations.
  • The client i18n approach (English SSG first paint + JS swap) with per-language SEO routes intentionally deferred — acceptable for now?
  • site/ as a top-level dir outside packages/* (independent Cloudflare Pages deploy). No CI / deploy workflow wired yet.

Risk Notes

  • No CI / deploy workflow is wired for site/ yet; the build is verified locally only.
  • OG image uses the app icon as a placeholder; needs a dedicated 1200×630 share image.
  • Download links are GitHub Releases pages, not direct installers, until [Feature] Updater reliability for mainland China (non-GitHub mirror / CDN) #219 lands.
  • Routing label: site/ is not covered by the existing labeler path rules; applied ui as the closest fit — a maintainer may prefer a new site label.
  • Skipped conditional checklist item — platform/packaging: this PR only adds a static web page; no Electron shell, updater, packaging, signing, paths, or permissions surface is touched.

How To Verify

bun install: 255 packages, ok
bun run build: 1 page built, static output, no errors
Visual check (Chrome headless against `astro preview`, ?lang= & theme= forced):
  all four combos render and match the design — en/light, en/dark, cn/light, cn/dark
  language toggle swaps copy + brand (PawWork <-> 爪印); theme toggle swaps light/dark; both persist
First-paint HTML asserts English copy + SEO title/description/canonical/OG present

Screenshots or Recordings

Verified the four EN/CN × light/dark combinations locally via Chrome headless against astro preview (?lang=en|cn&theme=light|dark). Layout matches the approved design: paw logo + single floating chip, full-width primary download button over two equal secondary buttons, three capability cards. EN/light and CN/dark shared with the maintainer in-session.

Checklist

  • Type label — this PR carries exactly one of bug, enhancement, task, documentation. Type labels are author-added; the labeler bot does NOT assign them. Add the label in the GitHub UI, then tick this.
  • Routing labels — this PR carries at least one of app, ui, platform, harness, ci. The labeler bot assigns these on PR open based on changed paths. Confirm the bot's choice (or override if wrong), then tick this.
  • Priority label — this PR carries exactly one of P0, P1, P2, P3. The priority-triage bot suggests one on PR open. Confirm or override, then tick this.
  • Human Review Status above is set to Pending, Approved by @<reviewer>, or Not required: <reason> (default is Pending; "not required" is restricted to bot-authored low-risk PRs).
  • I linked the related issue, or stated in Summary why there is no issue.
  • I described the review focus and any meaningful risks.
  • I replaced the example block in How To Verify with the real verification steps and the key result for each.
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope.
  • (conditional) I manually checked visible UI or copy changes when needed, with screenshots or recordings. Leave unticked only if no visible UI or copy changed.
  • (conditional) I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes. Leave unticked only if no platform/packaging surface was touched.
  • (conditional) I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant. Leave unticked only if none of those surfaces was touched.
  • I reviewed the final diff for unrelated changes and suspicious dependency changes.
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English.

Summary by CodeRabbit

  • New Features

    • Added a dedicated PawWork download landing page with localized download links
    • Language switch (English/Chinese) with persistent preference
    • Dark/light theme toggle with persistence
    • SEO & social preview metadata (canonical URLs and OG/Twitter image placeholder)
    • Fully responsive design for desktop and mobile
  • Documentation

    • Added site setup, development, and deployment notes in the site README

Review Change Stack

Standalone Astro static site under site/ for the PawWork download landing
page. Plain CSS (no UI framework); deploys to Cloudflare Pages independently
of the desktop app build.

- Ported from the approved design (2026-05-30 download-landing final)
- English first paint for basic SEO; client-side EN/中 and light/dark toggles,
  persisted in localStorage; anti-flash theme script in <head>
- Download buttons point at the GitHub Releases page for now; China-hosted
  direct links to follow with the updater fallback (#219)
- Per-language SEO routes intentionally deferred
@Astro-Han Astro-Han added enhancement New feature or request P2 Medium priority ui Design system and user interface labels May 30, 2026
@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Astro-Han, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 27 minutes and 52 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 565bef0e-51f8-41f3-bbdd-ed318c3c5cbf

📥 Commits

Reviewing files that changed from the base of the PR and between 3318805 and c454a3f.

📒 Files selected for processing (3)
  • .github/workflows/deploy-site.yml
  • site/README.md
  • site/src/pages/index.astro
📝 Walkthrough

Walkthrough

Adds a new Astro-based static site under site/ (content, i18n, layout, styles), a GitHub Actions workflow to build/deploy the site to Cloudflare Pages, and updates labeling/tests to include site/** changes.

Changes

PawWork Download Landing Page Site

Layer / File(s) Summary
Project setup and configuration
site/package.json, site/astro.config.mjs, site/tsconfig.json, site/.gitignore, site/README.md
Establishes the Astro project with ESM package metadata, site origin config, TypeScript strict setup, git ignores for the site, and developer README with dev/build commands and notes.
Site content and data
site/src/config.ts, site/src/i18n.ts
Exports repository/release URLs, download link mapping, and a bilingual (EN/CN) translation dictionary with types used by the site.
Base layout and SEO
site/src/layouts/Base.astro
Provides a shared HTML layout with canonical/OG/Twitter meta tags and an inline script that applies initial theme preference before first paint.
Landing page and interactivity
site/src/pages/index.astro
Renders the landing page UI with navigation, language/theme toggles, download buttons, and an inline client script that selects/applies language and theme and persists preferences.
Global styling and design system
site/src/styles/global.css
Adds the complete stylesheet: theme tokens, base resets, animations, component styles (header, hero, mock UI, capabilities, footer), and responsive breakpoints.
CI/CD, labeling, and tests
.github/workflows/deploy-site.yml, .github/labeler.yml, packages/opencode/test/github/bun-version-workflow.test.ts
Adds a workflow to build (on PRs touching site/**) and deploy the site to Cloudflare Pages from dev, extends labeler to include site/**, and updates the Bun-version pin test to expect 1.3.14.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

ui, github_actions

"I hopped and stitched a tiny site so bright,
Astro pages ready, day and night,
English, Chinese—both in tune,
Dark mode glows beneath the moon,
Deploys take flight on clouded light." 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(site): add download landing page' clearly and concisely summarizes the main change—adding a new Astro-based download landing page under the site/ directory.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering Summary, Why, Related Issue, Human Review Status, Review Focus, Risk Notes, How To Verify, Screenshots, and a complete checklist. All major sections align with the template.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/download-landing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot removed the ui Design system and user interface label May 30, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested priority: P2 (includes non-doc, non-test paths outside the low-risk bucket).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a static landing page for PawWork built with Astro, featuring plain CSS styling, light/dark theme toggles, and client-side English/Chinese language switching. The code review feedback suggests several improvements to enhance client-side robustness and user experience, including wrapping localStorage access in a try-catch block to avoid security errors, checking for the existence of DOM elements before binding event listeners, dynamically updating the document title upon language changes, and centralizing the SEO title within the i18n dictionary to eliminate duplication.

Comment thread site/src/pages/index.astro Outdated
Comment thread site/src/pages/index.astro Outdated
Comment thread site/src/pages/index.astro
Comment thread site/src/i18n.ts
Comment thread site/src/i18n.ts
Comment thread site/src/pages/index.astro
The actions/labeler config had no path rule for the new site/ directory, so
pr-triage failed with "must have at least one primary routing label".
Add site/** to the ui glob set.
@github-actions github-actions Bot added the ci Continuous integration / GitHub Actions label May 30, 2026
@Astro-Han Astro-Han added the ui Design system and user interface label May 30, 2026
@github-actions github-actions Bot removed the ui Design system and user interface label May 30, 2026
Astro-Han added 2 commits May 30, 2026 11:32
Triggers on push to dev when site/ changes, or via manual dispatch.
Uses wrangler-action to deploy the Astro static build to Cloudflare Pages.

Requires two repository secrets:
- CLOUDFLARE_ACCOUNT_ID
- CLOUDFLARE_API_TOKEN (with Pages edit permission)
- Add title to i18n dictionaries and reference it from seoTitle to
  eliminate duplication
- Update document.title on language switch so the browser tab reflects
  the active language
- Wrap localStorage.getItem in try-catch for strict privacy environments
- Use optional chaining on toggle event listeners for defensive safety

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
.github/workflows/deploy-site.yml (1)

20-22: ⚡ Quick win

Consider adding deployment environment tracking.

Adding an environment: field enables GitHub's deployment tracking UI, providing visibility into deployment history, status, and protection rules.

📊 Proposed enhancement for deployment visibility
   deploy:
     runs-on: ubuntu-latest
     timeout-minutes: 5
+    environment:
+      name: cloudflare-pages-dev
+      url: https://pawwork.pages.dev
     steps:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/deploy-site.yml around lines 20 - 22, The deploy job
currently defined with the job name "deploy" and keys "runs-on" and
"timeout-minutes" lacks an environment declaration for GitHub deployment
tracking; add an environment: block (for example environment: name: production
or environment: name: ${{ secrets.DEPLOY_ENV }}) under the deploy job to enable
deployment history, status, and protection rules in GitHub UI.
site/src/pages/index.astro (1)

59-63: ⚡ Quick win

Consider adding ARIA state attributes to toggle buttons.

The language and theme toggle buttons have aria-label attributes but lack state indicators. Adding aria-pressed or aria-checked would improve accessibility by announcing the current state to screen reader users.

♿ Suggested enhancement for accessibility

Update the client-side script to set ARIA state attributes when applying theme/language:

 function applyLang(l) {
   root.setAttribute("data-lang", l);
   root.setAttribute("lang", l === "cn" ? "zh" : "en");
+  lg?.setAttribute("aria-pressed", l === "cn" ? "false" : "true");
   const dict = I18N[l];
 function applyTheme(theme) {
   root.setAttribute("data-theme", theme);
+  tg?.setAttribute("aria-pressed", theme === "dark" ? "true" : "false");
   try {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@site/src/pages/index.astro` around lines 59 - 63, The toggle buttons with ids
"lg" and "tg" lack ARIA state attributes—update the client-side script that
handles language and theme toggles to set and update an appropriate ARIA state
(e.g., aria-pressed="true"/"false" or aria-checked="true"/"false") on the
elements with id "lg" and "tg" (and any elements with class "toggle") whenever
their state changes, ensure the initial state is set on page load to reflect the
current language/theme, and keep the attribute in sync whenever the UI or
persisted preference changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/deploy-site.yml:
- Around line 26-28: Replace the non-deterministic step using "uses:
oven-sh/setup-bun@..." that currently passes bun-version: latest by pinning
bun-version to a specific released version (replace "latest" with an explicit
version string) and disable the action's caching (add the cache: false input) to
prevent cache poisoning from forked PRs; update the action invocation that
references "uses: oven-sh/setup-bun@..." and the "bun-version" and "cache"
inputs accordingly.
- Line 24: The checkout step currently uses actions/checkout without disabling
credential persistence; update the checkout step (the actions/checkout@...
invocation) to include a "with: persist-credentials: false" option so GitHub
credentials are not persisted to the runner or artifacts — locate the line
containing "uses: actions/checkout@de0fac2e..." and add the persist-credentials:
false setting under its "with" configuration.

In `@site/README.md`:
- Around line 16-25: Update the fenced code block in README.md that begins with
the directory listing (the block showing "src/" and "public/") to include a
language specifier (e.g., change ``` to ```text) so the markdown linter accepts
it and rendering is consistent; locate the block containing the lines "src/",
"pages/index.astro", "layouts/Base.astro", "styles/global.css", "i18n.ts",
"config.ts", and "public/" and add the language token immediately after the
opening backticks.

In `@site/src/pages/index.astro`:
- Line 122: The lang attribute uses a generic "zh" tag; update the call to
root.setAttribute in the file so that when l === "cn" it sets a BCP 47 locale
like "zh-CN" (instead of "zh") to correctly indicate Simplified Chinese; keep
the existing conditional logic (root.setAttribute and variable l) but replace
the value for the "cn" branch with "zh-CN".

---

Nitpick comments:
In @.github/workflows/deploy-site.yml:
- Around line 20-22: The deploy job currently defined with the job name "deploy"
and keys "runs-on" and "timeout-minutes" lacks an environment declaration for
GitHub deployment tracking; add an environment: block (for example environment:
name: production or environment: name: ${{ secrets.DEPLOY_ENV }}) under the
deploy job to enable deployment history, status, and protection rules in GitHub
UI.

In `@site/src/pages/index.astro`:
- Around line 59-63: The toggle buttons with ids "lg" and "tg" lack ARIA state
attributes—update the client-side script that handles language and theme toggles
to set and update an appropriate ARIA state (e.g., aria-pressed="true"/"false"
or aria-checked="true"/"false") on the elements with id "lg" and "tg" (and any
elements with class "toggle") whenever their state changes, ensure the initial
state is set on page load to reflect the current language/theme, and keep the
attribute in sync whenever the UI or persisted preference changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f09ca9f1-3c51-49bc-9dbd-7e6989a36528

📥 Commits

Reviewing files that changed from the base of the PR and between 6eb8585 and 14af166.

⛔ Files ignored due to path filters (2)
  • site/bun.lock is excluded by !**/*.lock
  • site/public/app-icon.svg is excluded by !**/*.svg
📒 Files selected for processing (12)
  • .github/labeler.yml
  • .github/workflows/deploy-site.yml
  • site/.gitignore
  • site/README.md
  • site/astro.config.mjs
  • site/package.json
  • site/src/config.ts
  • site/src/i18n.ts
  • site/src/layouts/Base.astro
  • site/src/pages/index.astro
  • site/src/styles/global.css
  • site/tsconfig.json

Comment thread .github/workflows/deploy-site.yml
Comment thread .github/workflows/deploy-site.yml Outdated
Comment thread site/README.md Outdated
Comment thread site/src/pages/index.astro Outdated
Astro-Han added 2 commits May 30, 2026 12:14
Address review feedback:
- Pin bun-version to 1.3.14 to match the rest of the workflows (was: latest)
- Trigger on pull_request (site/** paths) so build breaks surface in the PR
  instead of after merge; the Cloudflare deploy step is skipped for PRs
- Scope concurrency group by ref so PR build-checks don't cancel dev deploys
The bun-version-workflow guard test enumerates every setup-bun step and
requires the audit-version comment above each bun-version line. The new
deploy-site workflow tripped both checks; register its pin in the expected
list and add the audit comment so the guard stays green.
@github-actions github-actions Bot added the harness Model harness, prompts, tool descriptions, and session mechanics label May 30, 2026
Astro-Han and others added 4 commits May 30, 2026 12:37
- The pinned wrangler-action SHA did not exist, so the deploy-site job failed
  at 'Set up job' (Unable to resolve action). Repin to the v3 commit
  9acf94ac that GitHub actually resolves.
- Gate the deploy step on github.ref == 'refs/heads/dev' instead of just
  'not a PR', so a manual workflow_dispatch from another branch build-checks
  only and can't publish non-dev content to the fixed --branch=dev target.
The mobile media query only handled hero/cards; the nav could overflow and
clip the GitHub/language/theme controls on narrow screens. Add a <=600px
breakpoint that tightens padding, shrinks the brand, and drops the secondary
'What it does' anchor so everything fits down to ~320px.
Address still-valid bot review findings on PR #992:
- deploy-site checkout: set persist-credentials: false (zizmor artipacked
  hardening; the deploy step uses separate Cloudflare credentials)
- lang switch: use BCP 47 zh-CN instead of generic zh for Simplified Chinese
- README structure block: add text language specifier (markdownlint MD040)

Other bot suggestions (i18n title keys, SEO title dedup, document.title on
language switch) were already implemented in earlier commits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Astro-Han Astro-Han merged commit 1e0fa1f into dev May 30, 2026
27 checks passed
@Astro-Han Astro-Han deleted the claude/download-landing branch May 30, 2026 10:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci Continuous integration / GitHub Actions enhancement New feature or request harness Model harness, prompts, tool descriptions, and session mechanics P2 Medium priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant