{"id":44925028,"url":"https://github.com/gsinghjay/astro-shadcn-sanity","last_synced_at":"2026-06-04T07:00:44.553Z","repository":{"id":338884338,"uuid":"1152033716","full_name":"gsinghjay/astro-shadcn-sanity","owner":"gsinghjay","description":"A CMS-driven static website for NJIT's Ying Wu College of Computing Industry Capstone program. Content editors compose pages by stacking reusable UI blocks in Sanity Studio — zero code required.","archived":false,"fork":false,"pushed_at":"2026-05-10T02:08:24.000Z","size":87019,"stargazers_count":2,"open_issues_count":56,"forks_count":1,"subscribers_count":0,"default_branch":"preview","last_synced_at":"2026-05-10T02:44:46.406Z","etag":null,"topics":["astro","cloudflare","cloudflare-d1","cloudflare-pages","cloudflare-workers","jamstack","lighthouse-ci","playwright","sanity-io","sanity-studio","semantic-release","shadcn-ui","storybook","tailwindcss","vitest"],"latest_commit_sha":null,"homepage":"https://gsinghjay-astro-shadcn-sanity.mintlify.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gsinghjay.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"docs/security-audit-2026-04-30.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-07T08:59:28.000Z","updated_at":"2026-05-10T00:22:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gsinghjay/astro-shadcn-sanity","commit_stats":null,"previous_names":["gsinghjay/astro-shadcn-sanity"],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/gsinghjay/astro-shadcn-sanity","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsinghjay%2Fastro-shadcn-sanity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsinghjay%2Fastro-shadcn-sanity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsinghjay%2Fastro-shadcn-sanity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsinghjay%2Fastro-shadcn-sanity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gsinghjay","download_url":"https://codeload.github.com/gsinghjay/astro-shadcn-sanity/tar.gz/refs/heads/preview","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gsinghjay%2Fastro-shadcn-sanity/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33893323,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["astro","cloudflare","cloudflare-d1","cloudflare-pages","cloudflare-workers","jamstack","lighthouse-ci","playwright","sanity-io","sanity-studio","semantic-release","shadcn-ui","storybook","tailwindcss","vitest"],"created_at":"2026-02-18T04:06:00.435Z","updated_at":"2026-06-04T07:00:44.547Z","avatar_url":"https://github.com/gsinghjay.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# YWCC Industry Capstone\n\n![Astro](https://img.shields.io/badge/Astro-5.x-FF5D01?logo=astro\u0026logoColor=white)\n![Sanity](https://img.shields.io/badge/Sanity-5-F03E2F?logo=sanity\u0026logoColor=white)\n![Tailwind CSS](https://img.shields.io/badge/Tailwind_CSS-4-06B6D4?logo=tailwindcss\u0026logoColor=white)\n![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?logo=typescript\u0026logoColor=white)\n![Vite](https://img.shields.io/badge/Vite-7-646CFF?logo=vite\u0026logoColor=white)\n![Cloudflare Pages](https://img.shields.io/badge/Cloudflare_Pages-F38020?logo=cloudflarepages\u0026logoColor=white)\n![Storybook](https://img.shields.io/badge/Storybook-10-FF4785?logo=storybook\u0026logoColor=white)\n![Vitest](https://img.shields.io/badge/Vitest-6CB33E?logo=vitest\u0026logoColor=white)\n![Playwright](https://img.shields.io/badge/Playwright-2EAD33?logo=playwright\u0026logoColor=white)\n![semantic-release](https://img.shields.io/badge/semantic--release-494949?logo=semanticrelease\u0026logoColor=white)\n![Node.js](https://img.shields.io/badge/Node.js-24+-5FA04E?logo=nodedotjs\u0026logoColor=white)\n![npm workspaces](https://img.shields.io/badge/npm_workspaces-monorepo-CB3837?logo=npm\u0026logoColor=white)\n\nA CMS-driven static website for NJIT's Ying Wu College of Computing Industry Capstone program. Content editors compose pages by stacking reusable UI blocks in Sanity Studio — zero code required.\n\n```mermaid\nflowchart LR\n    Editor[Content Editor] --\u003e|Compose pages| Studio[Sanity Studio]\n    Studio --\u003e|Webhook trigger| Build[Astro SSG Build]\n    Build --\u003e|Static HTML| CF[Cloudflare Pages]\n    Visitor[Site Visitor] --\u003e|Browse| CF\n    Visitor --\u003e|Submit form| Worker[CF Worker]\n    Worker --\u003e|Store submission| Sanity[(Sanity CMS)]\n```\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Tech Stack](#tech-stack)\n- [Project Structure](#project-structure)\n- [Prerequisites](#prerequisites)\n- [Getting Started](#getting-started)\n- [Development](#development)\n- [Git Workflow](#git-workflow)\n- [Block Library](#block-library)\n- [Content Model](#content-model)\n- [Adding a New Block](#adding-a-new-block)\n- [Testing](#testing)\n- [Deployment](#deployment)\n- [Performance Targets](#performance-targets)\n- [Contributing](#contributing)\n- [Team](#team)\n- [Resources](#resources)\n- [License](#license)\n\n## Overview\n\nThe platform connects industry sponsors with capstone teams by showcasing sponsor organizations, project proposals, team rosters, and program information. It uses a **toolkit-not-website** approach — a block library maps editor-friendly names to [fulldev/ui](https://ui.full.dev) component internals (vanilla Astro components via the shadcn CLI), making the design system invisible to non-technical users.\n\n**Key goals:**\n\n- Content editors build and update pages independently with no developer involvement\n- Prospective sponsors discover the program and submit inquiries\n- Students find team assignments, project details, and key dates in one hub\n- $0/month operating cost using free tiers across all services\n- Lighthouse 90+ across all categories on every page\n\n**Reference site:** [ywcccapstone1.com](https://ywcccapstone1.com)\n\n## Tech Stack\n\n| Layer | Technology |\n|---|---|\n| Frontend | [Astro 5.x](https://astro.build/) (SSG, `output: 'static'`) |\n| CMS | [Sanity 5](https://www.sanity.io/) (headless, Visual Editing) |\n| UI Components | [fulldev/ui](https://ui.full.dev) — vanilla `.astro` components via shadcn CLI |\n| Styling | [Tailwind CSS v4](https://tailwindcss.com/) (`@tailwindcss/vite`, CSS-first config) |\n| Icons | [@iconify/utils](https://iconify.design/) + Lucide (`@iconify-json/lucide`, `@iconify-json/simple-icons`) |\n| Interactivity | Vanilla JS (\u003c 5KB total) |\n| Hosting | [Cloudflare Pages](https://pages.cloudflare.com/) (production: static, preview: SSR) |\n| Storybook | [GitHub Pages](https://pages.github.com/) (component library only) |\n| Form Proxy | [Cloudflare Worker](https://workers.cloudflare.com/) (deferred) |\n| Analytics | GA4 + Monsido |\n| Unit Tests | [Vitest](https://vitest.dev/) (jsdom) |\n| E2E Tests | [Playwright](https://playwright.dev/) (5 browser projects + axe-core a11y) |\n| CI/CD | [GitHub Actions](https://github.com/features/actions) (CI, release, Storybook deploy) |\n| Releases | [semantic-release](https://semantic-release.gitbook.io/) (automated versioning + changelog) |\n| Component Dev | [Storybook 10](https://storybook.js.org/) (via `storybook-astro` renderer) |\n\nProduction builds bake all content into static HTML — zero runtime API calls. The `preview` branch uses SSR for live Visual Editing with draft content.\n\n## Project Structure\n\n```text\nastro-shadcn-sanity/\n├── astro-app/                # Astro frontend (SSG)\n│   ├── astro.config.mjs      # output: 'static', @tailwindcss/vite, @sanity/astro\n│   ├── components.json       # shadcn CLI config with @fulldev registry\n│   ├── src/\n│   │   ├── components/\n│   │   │   ├── ui/           # fulldev/ui primitives (installed via shadcn CLI)\n│   │   │   ├── blocks/       # Block components\n│   │   │   │   ├── custom/   # Custom blocks with business logic (11)\n│   │   │   │   └── *.astro   # fulldev/ui template blocks (100+ variants)\n│   │   │   ├── block-registry.ts  # Unified block map (auto-discovers all blocks)\n│   │   │   ├── BlockRenderer.astro # Single dispatch: allBlocks[_type] → spread props\n│   │   │   └── *.astro       # Layout components (Header, Footer, etc.)\n│   │   ├── layouts/          # Base HTML layout\n│   │   ├── lib/              # Sanity client, GROQ queries, image helpers\n│   │   ├── pages/            # Astro page routes\n│   │   └── styles/\n│   │       └── global.css    # @import \"tailwindcss\" + theme + CSS variables\n│   └── package.json\n├── studio/                   # Sanity Studio (CMS)\n│   └── src/\n│       └── schemaTypes/\n│           ├── blocks/       # Block object schemas (one per block)\n│           ├── documents/    # Document schemas (page, sponsor, etc.)\n│           ├── objects/      # Shared objects (SEO, button, portable text)\n│           └── helpers/      # defineBlock helper\n├── .github/workflows/        # CI, release, Storybook deploy, branch enforcement\n├── docs/team/                # Developer guides and onboarding\n├── tests/                    # Playwright tests\n├── package.json              # Root workspace config\n├── .releaserc.json           # semantic-release configuration\n└── CHANGELOG.md              # Auto-generated (do not edit manually)\n```\n\nThis is an **npm workspaces** monorepo with two packages: `astro-app` and `studio`.\n\n## Prerequisites\n\n- [Node.js](https://nodejs.org/) v24 or later\n- npm v10 or later\n- A [Sanity.io](https://www.sanity.io/) account (free tier)\n- A [GitHub](https://github.com/) account\n- A [Cloudflare](https://www.cloudflare.com/) account (free tier, for deployment)\n\n## Getting Started\n\n### 1. Clone the repository\n\n```bash\ngit clone git@github.com:gsinghjay/astro-shadcn-sanity.git\ncd astro-shadcn-sanity\n```\n\n### 2. Install dependencies\n\n```bash\nnpm install\n```\n\nThis command installs dependencies for both the Astro app and Sanity Studio.\n\n### 3. Configure environment variables\n\nCreate a `.env` file in `astro-app/` with your Sanity project credentials:\n\n```bash\nPUBLIC_SANITY_PROJECT_ID=your_project_id\nPUBLIC_SANITY_DATASET=production\n```\n\n### 4. Start development servers\n\n```bash\nnpm run dev\n```\n\nThis starts both servers concurrently:\n\n- **Astro app:** \u003chttp://localhost:4321\u003e\n- **Sanity Studio:** \u003chttp://localhost:3333\u003e\n\n### 5. Sign in to Sanity Studio\n\nOpen \u003chttp://localhost:3333\u003e and sign in with the same service (Google, GitHub, or email) you used when creating your Sanity project.\n\n## Development\n\n| Command | What it does |\n|---|---|\n| `npm run dev` | Start Astro + Studio dev servers |\n| `npm run dev:storybook` | Start Astro + Studio + Storybook (all three) |\n| `npm run storybook` | Start Storybook alone (port 6006) |\n| `npm run build --workspace=astro-app` | Build Astro for production |\n| `npm run test:unit` | Run Vitest unit tests |\n| `npm run test:unit:watch` | Unit tests in watch mode |\n| `npm run test` | Run Playwright E2E tests (builds first) |\n| `npm run test:integration` | Run integration tests (fast, no browser) |\n| `npm run test:ui` | Run Playwright in UI mode |\n\n## Git Workflow\n\nWe use [Conventional Commits](https://www.conventionalcommits.org/) + [semantic-release](https://semantic-release.gitbook.io/) for automated versioning and changelog generation.\n\n```mermaid\nflowchart TD\n    A[feature/* branch] --\u003e|PR, CI must pass| B[preview branch]\n    B --\u003e|PR, code owner approval| C[main branch]\n    C --\u003e|automatic| D[semantic-release]\n    D --\u003e E[Version bump + CHANGELOG + GitHub Release]\n    E --\u003e F[Sync preview with main]\n    F --\u003e G[Discord notification]\n```\n\n### Branch rules\n\n| Branch | Purpose | Protection |\n|---|---|---|\n| `main` | Production releases | PRs only from `preview`, code owner approval required |\n| `preview` | Staging/integration | PRs only, CI must pass (unit tests + Lighthouse) |\n| `feature/*` | Your working branches | No restrictions |\n\n### Commit format\n\n```text\n\u003ctype\u003e: \u003cdescription\u003e\n```\n\n| Prefix | Release? | Version bump |\n|---|---|---|\n| `feat:` | Yes | Minor (0.1.0 → 0.2.0) |\n| `fix:` | Yes | Patch (0.1.0 → 0.1.1) |\n| `feat!:` | Yes | Major (0.1.0 → 1.0.0) |\n| `chore:`, `docs:`, `ci:`, `test:`, `refactor:` | No | — |\n\nSee [docs/team/git-workflow-guide.md](docs/team/git-workflow-guide.md) for the full guide with examples and troubleshooting.\n\n## Block Library\n\nPages are composed from a flat array of reusable CMS blocks. All blocks — custom and template — dispatch through a single unified registry with spread props.\n\n```mermaid\nflowchart LR\n    Page[\"Page (blocks[])\"] --\u003e BR[\"BlockRenderer\"]\n    BR --\u003e Reg[\"block-registry.ts\"]\n    Reg --\u003e|\"allBlocks[_type]\"| BW[\"BlockWrapper\"]\n    BW --\u003e|\"\u003cComponent {...block} /\u003e\"| C[\"Block Component\"]\n```\n\n### Block Architecture\n\n| Category | Location | Count | Description |\n|---|---|---|---|\n| Custom blocks | `blocks/custom/` | 11 | Business logic, CMS-connected, Sanity schemas + GROQ projections |\n| Template blocks | `blocks/` | 100+ | [fulldev/ui](https://ui.full.dev) variants, CMS connection in progress |\n\nBoth categories use the same flat-props interface (`interface Props extends BlockType`) and are auto-discovered by `block-registry.ts` — no manual registration required.\n\n### Custom Blocks (CMS-Connected)\n\n| Block | Description |\n|---|---|\n| Hero Banner | Heading, subheading, optional background image carousel, CTA buttons, configurable alignment |\n| Feature Grid | Icon/image + title + description cards in configurable column layouts |\n| Sponsor Cards | Sponsor documents with tier badges and display modes |\n| Rich Text | Portable Text with inline images and callout boxes |\n| CTA Banner | Heading, description, and action buttons with variant-aware styling |\n| FAQ Section | Expandable question/answer pairs with keyboard accessibility |\n| Contact Form | Configurable fields with server-side submission via Cloudflare Worker |\n| Stats Row | Heading + stat cards with dark/light variant support |\n| Text with Image | Portable text content alongside a positioned image |\n| Logo Cloud | Sponsor logos from sponsor documents |\n| Sponsor Steps | Numbered step-by-step process cards |\n\n### Template Blocks (fulldev/ui)\n\n102 pre-built design variants across 12 categories, installed via `npx shadcn@latest add @fulldev/{name}`:\n\n| Category | Variants | Examples |\n|---|---|---|\n| Heroes | 14 | `hero-1` through `hero-14` — headline + CTA + image layouts |\n| Features | 6 | `features-1` through `features-6` — icon/card grid layouts |\n| Content | 6 | `content-1` through `content-6` — text + image sections |\n| CTA | 8 | `cta-1` through `cta-8` — call-to-action banners |\n| Pricing | 3 | `pricings-1` through `pricings-3` — tier comparison cards |\n| Reviews | 5 | `reviews-1` through `reviews-5` — testimonial layouts |\n| Services | 7 | `services-1` through `services-7` — service card grids |\n| Articles | 6 | `article-1`, `article-2`, `articles-1` through `articles-4` |\n| Media | 9 | `logos-*`, `images-*`, `video-*`, `videos-*` |\n| Navigation | 6 | `header-1` through `header-3`, `footer-1` through `footer-3` |\n| FAQ/Steps | 7 | `faqs-1` through `faqs-4`, `steps-1` through `steps-3` |\n| Misc | 25 | `banner-*`, `stats-*`, `contact-*`, `links-*`, `table-1`, etc. |\n\nThese blocks have Storybook stories with demo data. Sanity schema + GROQ projection wiring is tracked in Stories 2.4–2.8. See [fulldev/ui to Sanity Conversion Guide](docs/team/fulldev-ui-to-sanity-conversion-guide.md).\n\n## Content Model\n\n```mermaid\nerDiagram\n    PAGE ||--o{ BLOCK : contains\n    SPONSOR ||--o{ PROJECT : funds\n    PROJECT ||--|| TEAM : \"assigned to\"\n    PROJECT }o--|| SPONSOR : references\n    TEAM }o--|| PROJECT : references\n    EVENT ||--o| PAGE : \"displayed on\"\n    SUBMISSION }o--|| SPONSOR : \"inquiry from\"\n    SITE_SETTINGS ||--|| PAGE : configures\n\n    PAGE {\n        string title\n        slug slug\n        array blocks\n        object seo\n    }\n    SPONSOR {\n        string name\n        image logo\n        string description\n        url website\n        string industry\n        string tier\n        boolean featured\n    }\n    PROJECT {\n        string title\n        text description\n        reference sponsor\n        array techTags\n        reference team\n        string semester\n        string status\n    }\n    TEAM {\n        array members\n        reference project\n        reference advisor\n    }\n    EVENT {\n        string title\n        date date\n        string location\n        text description\n        string type\n    }\n    SUBMISSION {\n        string name\n        string organization\n        string email\n        text message\n    }\n    SITE_SETTINGS {\n        string siteName\n        image logo\n        array navigation\n        object footer\n        array socialLinks\n        string currentSemester\n    }\n```\n\n**7 document types:** Page, Sponsor, Project, Team, Event, Submission, Site Settings.\n\n## Adding a New Block\n\nThere are two paths depending on the block type.\n\n### Path A: New Custom Block (with business logic)\n\nUse this when you need custom rendering logic, Sanity document references, or Portable Text.\n\n#### 1. Create the Sanity schema\n\nUse the `defineBlock` helper (merges shared base fields automatically):\n\n```typescript\n// studio/src/schemaTypes/blocks/your-block.ts\nimport { defineBlock } from '../helpers/defineBlock'\n\nexport const yourBlock = defineBlock({\n  name: 'yourBlock',\n  title: 'Your Block',\n  fields: [\n    // Block-specific fields only — base fields added by defineBlock\n  ],\n})\n```\n\n#### 2. Register the schema\n\nAdd to `studio/src/schemaTypes/index.ts` and the page schema's `blocks[]` array.\n\n#### 3. Install needed fulldev/ui primitives\n\n```bash\nnpx shadcn@latest add @fulldev/button @fulldev/badge  # whatever the block needs\n```\n\n#### 4. Create the Astro component\n\nAll blocks use the flat-props pattern — `interface Props extends YourBlockType`:\n\n```astro\n---\n// astro-app/src/components/blocks/custom/YourBlock.astro\nimport type { YourBlockBlock } from '@/lib/types'\nimport { Button } from '@/components/ui/button'\n\ninterface Props extends YourBlockBlock {\n  class?: string\n  id?: string\n}\n\nconst { heading, description, ctaButtons, backgroundVariant } = Astro.props\n---\n\n\u003csection\u003e\n  \u003ch2\u003e{heading}\u003c/h2\u003e\n  \u003c!-- Compose from ui/ primitives + Tailwind utilities --\u003e\n\u003c/section\u003e\n```\n\nThe component is auto-discovered by `block-registry.ts` — no manual registration needed. The filename determines the `_type` mapping: `YourBlock.astro` maps to `yourBlock`.\n\n#### 5. Add GROQ projection\n\nAdd the type-specific projection in `src/lib/sanity.ts`. Run `npm run typegen` to generate types.\n\nBuild and verify Lighthouse scores hold at 90+.\n\n### Path B: Wire a fulldev/ui Template Block to Sanity\n\nUse this when connecting an existing `blocks/*.astro` template to the CMS. The `.astro` component stays unchanged — you only add the data pipeline.\n\n#### 1. Create the Sanity schema\n\nMap the component's `Props` interface to Sanity field types. The GROQ projection reshapes Sanity's structured data back to match the component's expected props:\n\n```text\nSanity Schema (structured) → GROQ Projection (adapter) → Component Props (flat)\n```\n\n#### 2. Register schema + add GROQ projection + run TypeGen\n\nSee [fulldev/ui to Sanity Conversion Guide](docs/team/fulldev-ui-to-sanity-conversion-guide.md) for the full 7-step process and patterns for images, links, nested arrays, and more.\n\n**Files touched per block:** 4 (schema file, schema index, page schema, GROQ query). No `.astro` changes.\n\n## Testing\n\n| Layer | Tool | Command | What it tests |\n|---|---|---|---|\n| Unit | Vitest | `npm run test:unit` | Utilities, GROQ queries, mock data, DOM scripts |\n| Integration | Playwright | `npm run test:integration` | Schema validation, module imports |\n| E2E | Playwright | `npm run test` | Full browser tests across 5 device configs |\n| Accessibility | axe-core | Included in E2E | WCAG 2.1 AA compliance |\n| Performance | Lighthouse CI | CI only (preview PRs) | Core Web Vitals, performance budgets |\n\n## Deployment\n\n### Astro site → Cloudflare Pages\n\nDeployed automatically via Cloudflare Pages git integration:\n\n- **Push to `main`** → Production (static, Visual Editing OFF)\n- **Push to any branch** → Preview URL (SSR, Visual Editing ON)\n\nEnvironment variables are configured in the [Cloudflare Pages dashboard](https://dash.cloudflare.com/). See [docs/cloudflare-guide.md](docs/cloudflare-guide.md#6-environment-variables).\n\n### Sanity Studio\n\n```bash\nnpx sanity deploy --workspace=studio\n```\n\n### Storybook → GitHub Pages\n\nDeployed automatically via `.github/workflows/deploy-storybook.yml` on pushes to `main` that touch component files. Can also be triggered manually from the Actions tab.\n\n### Releases\n\nFully automated via [semantic-release](https://semantic-release.gitbook.io/). When `preview` merges into `main`:\n\n1. Commits are analyzed for version bump (based on conventional commit prefixes)\n2. `CHANGELOG.md` and `package.json` are updated\n3. A git tag and GitHub Release are created\n4. `preview` is auto-synced with `main`\n5. Discord notification confirms the sync\n\nSee the [CHANGELOG](CHANGELOG.md) and [GitHub Releases](https://github.com/gsinghjay/astro-shadcn-sanity/releases) for version history.\n\n## Performance Targets\n\n| Metric | Target |\n|---|---|\n| Lighthouse Performance | 95+ |\n| Lighthouse Accessibility | 90+ |\n| Cumulative Layout Shift | \u003c 0.05 |\n| JS payload | \u003c 5KB minified |\n| CSS payload | \u003c 15KB after Tailwind purge |\n\nOptimize for fast First Contentful Paint and Largest Contentful Paint on 4G connections. No framework runtime — Total Blocking Time stays near zero.\n\n## Contributing\n\n\u003e **Read the [Git Workflow Guide](docs/team/git-workflow-guide.md) before your first contribution.** It covers branch strategy, commit conventions, and the full release pipeline.\n\n1. Pull the latest `preview` branch: `git checkout preview \u0026\u0026 git pull`\n2. Create a feature branch: `git checkout -b feat/your-feature`\n3. Follow the [block checklist](#adding-a-new-block) for new blocks\n4. Write [conventional commits](#commit-format): `git commit -m \"feat: add your feature\"`\n5. Push and open a PR to `preview`: `gh pr create --base preview`\n6. After CI passes and merge, open a PR from `preview` → `main`\n7. Code owner reviews and merges → release happens automatically\n\n### Code conventions\n\n- **Sanity schemas:** TypeScript with `defineBlock` helper (blocks) or `defineType`/`defineField` (documents)\n- **UI primitives:** fulldev/ui components in `src/components/ui/` — install via `npx shadcn@latest add @fulldev/{name}`\n- **Custom block components:** `.astro` files in `src/components/blocks/custom/` composing from `ui/` primitives\n- **Template block components:** `.astro` files in `src/components/blocks/` — fulldev/ui variants installed via shadcn CLI\n- **Block dispatch:** Single unified registry (`block-registry.ts`) auto-discovers all blocks — no switch statements or manual registration\n- **Block props pattern:** All blocks receive flat spread props (`\u003cComponent {...block} /\u003e`). Extend the block type directly:\n  ```typescript\n  interface Props extends YourBlockType { class?: string; id?: string }\n  const { heading, description, backgroundVariant } = Astro.props  // direct access, not block.heading\n  ```\n- **Styling:** Tailwind v4 utility classes, CSS-first config in `global.css`, no `tailwind.config.mjs`\n- **Interactivity:** Vanilla JS with data-attribute driven event delegation, each handler under 50 lines\n- **Block architecture:** Flat array only — no nested blocks\n- **No React/JSX for page UI** — React is only for Sanity Visual Editing (Presentation tool)\n\n### Team documentation\n\n| Document | When to read it |\n|---|---|\n| [Git Workflow Guide](docs/team/git-workflow-guide.md) | Before your first commit |\n| [Onboarding Guide](docs/team/onboarding-guide.md) | First day setup |\n| [Cloudflare Guide](docs/cloudflare-guide.md) | Deployment, authentication, and environment variables |\n| [How Preview \u0026 Publish Works](docs/team/how-preview-and-publish-works.md) | Visual Editing and draft content |\n| [fulldev/ui to Sanity Conversion Guide](docs/team/fulldev-ui-to-sanity-conversion-guide.md) | Wiring template blocks to the CMS (Stories 2.4–2.8) |\n\n## Team\n\n| Name | GitHub | Role |\n|---|---|---|\n| Jay Singh | [@gsinghjay](https://github.com/gsinghjay) | Project Lead |\n| Roberson Sanchez | [@ras242](https://github.com/ras242)| - |\n| Sahil Parmar |[@SahilP20](https://github.com/SahilP20)| Discord Bot Dev |\n| Aryaan Panda |[@panzemary](https://github.com/panzemary)| - |\n| Mohsin Imtiaz | [@mi329-gif](https://github.com/mi329-gif) | Team Member |\n| Joshua Lastimosa | [@jo-las](https://github.com/jo-las) | Core Developer |\n| Pranav Chintala | [@pac27-cloud](https://github.com/pac27-cloud) | Team Member |\n| | | |\n| | | |\n\n\u003e **Team members:** Add your name, GitHub link, and role by editing this table on a feature branch and opening a PR to `preview`.\n\n## Resources\n\n- [Astro documentation](https://docs.astro.build/)\n- [Sanity documentation](https://www.sanity.io/docs/)\n- [fulldev/ui documentation](https://ui.full.dev/docs)\n- [Tailwind CSS v4 documentation](https://tailwindcss.com/docs)\n- [Cloudflare Pages documentation](https://developers.cloudflare.com/pages/)\n- [Conventional Commits](https://www.conventionalcommits.org/)\n- [semantic-release documentation](https://semantic-release.gitbook.io/)\n- [Storybook documentation](https://storybook.js.org/docs)\n- [Keep a Changelog](https://keepachangelog.com/)\n\n## License\n\nUNLICENSED\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgsinghjay%2Fastro-shadcn-sanity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgsinghjay%2Fastro-shadcn-sanity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgsinghjay%2Fastro-shadcn-sanity/lists"}