Marketing site and hackathon showcase for Hack Michigan — hackmichigan.com. Built with Astro 5, Three.js background animation, and Sanity for teams and project listings.
Deploy by connecting this repository to Vercel.
Release history: CHANGELOG.md.
- Landing experience — Hero, about, sponsors, event details, logistics, signup, and campaign CTA sections
- Hackathon area —
/projects/project grid, per-project pages, and team pages with optional member social links - Sanity CMS — Teams and hackathon projects; embedded Studio at
/studio(via@sanity/astro) - Three.js background — Particle field and wireframe accents (respects reduced motion; pause control)
- Design system — Scoped component styles plus tokens in
src/styles/global.css(self-hosted Tiny5 + Nunito) - Configurable imagery — Header brand, org logos, footer sponsors (
src/data/siteLogos.ts) - Analytics — Vercel Analytics (
@vercel/analytics) - TypeScript, sitemap, client-side transitions (
ClientRouter)
- Node.js >= 22.22.2 (see
package.jsonengines)
git clone https://github.com/Compass-Detroit/hackmi26.git
cd hackmi26
npm install
npm run devOpen http://localhost:4321.
# Production build
npm run build
# Preview build
npm run previewAstro site (astro.config.mjs) reads public Sanity vars via Vite loadEnv from the repo root .env* files, using the PUBLIC_ prefix only (so other secrets in those files are not loaded into the config object). Defaults match the shared HackMI project if unset:
PUBLIC_SANITY_PROJECT_ID=your_project_id
PUBLIC_SANITY_DATASET=production
PUBLIC_SANITY_STRICT_MODE=false- Set
PUBLIC_SANITY_STRICT_MODE=truein production to fail builds when Sanity fetches fail instead of silently shipping empty fallback content.
Standalone Studio (studio-hack-michigan-/) resolves project and dataset in sanity.env.ts:
SANITY_STUDIO_PROJECT_ID/SANITY_STUDIO_DATASET— use these to point local Studio or CLI at a non-production dataset without changing site build vars.- Otherwise falls back to the same
PUBLIC_SANITY_*names (handy if you duplicate vars instudio-hack-michigan-/.env). - Otherwise the same built-in defaults as the Astro config.
The Sanity CLI loads .env from studio-hack-michigan-/ when you run sanity dev or sanity deploy.
For Facebook Open Graph sharing you can set PUBLIC_FB_APP_ID (see src/env.d.ts).
The internal /deploy/ page posts to /api/trigger-deploy/, which forwards to an n8n webhook.
N8N_VERCEL_DEPLOY_WEBHOOK_URL=https://your-n8n-webhook.example
DEPLOY_TRIGGER_SECRET=shared_team_passphraseN8N_VERCEL_DEPLOY_WEBHOOK_URLis required for local/dev proxy and production API route.DEPLOY_TRIGGER_SECRETis required in production; when set, the API requires a matching passphrase.- Keep both as server-only vars (do not prefix with
PUBLIC_). - Deploy endpoint has in-memory rate limiting and a short post-success cooldown; still add edge/WAF rate limits in Vercel for stronger abuse protection.
The Studio app lives in studio-hack-michigan-/. Use it for a dedicated CMS dev server or deploys:
cd studio-hack-michigan-
npm install
npm run devSchemas: studio-hack-michigan-/schemaTypes/ (team, hackathonProject). Team members support optional profile URLs (GitHub, LinkedIn, X, Bluesky, Mastodon, Instagram, personal site).
| Source | What it drives |
|---|---|
src/data/*.ts |
Event copy, nav, agenda hints, external links |
src/data/siteLogos.ts |
Logos in header, footer, sections |
Sanity team / hackathonProject |
/projects/ listings, team and project detail routes |
Fetched in src/lib/sanity/ at build time for static pages.
- Prettier (including double quotes for JS/TS)
- ESLint (Astro + TypeScript)
- Stylelint for CSS in Astro/components
npm run format # write
npm run format:check # CI
npm run lint
npm run lint:css
npm run typecheck # astro check
npm run verify # format + lint + lint:css + typecheck + buildBy default, local runs use your installed Google Chrome (so you don’t need to download Playwright browser binaries).
If you don’t have Chrome installed (or you want Playwright-managed Chromium), install browsers once:
npm run playwright:installThen run the suite:
npm run test:e2e- Colors, type, motion tokens —
src/styles/global.css(:rootvariables) - Event name, dates, URLs —
src/data/event.ts - Astro —
astro.config.mjs(site URL, Sanity, MDX, sitemap)
src/
├── components/ # UI sections and primitives
├── data/ # Event, nav, logos, agenda (TypeScript)
├── layouts/ # BaseLayout (meta, fonts, transitions)
├── lib/ # sanity client helpers, constants
├── pages/ # Routes (index, projects/*)
├── styles/ # global.css
└── env.d.ts # Import meta env typings
studio-hack-michigan-/
├── schemaTypes/ # Sanity document schemas
├── sanity.config.ts
└── sanity.cli.ts
- Root — Astro site (
package.json,src/,astro.config.mjs). This is what Vercel builds. studio-hack-michigan-/— Sanity Studio (separatepackage.json). Run it when you are editing schemas or content outside the embedded/studioshell.
- Rendering — Static output (
output: "static"). Hackathon routes usegetStaticPaths()and load Sanity insrc/lib/sanity/at build time; a fullnpm run buildneeds the Sanity API reachable with the configured project/dataset. - Client navigation —
ClientRouterinBaseLayoutenables SPA-style transitions. Client scripts that must re-run after navigation should listen forastro:page-load(seeThreeBackground.astroand the layout cursor script). - Styles — Component-scoped
<style>blocks plus shared tokens insrc/styles/global.css. No Tailwind in this repo. - Paths — TypeScript path alias
~/*→src/*(seetsconfig.json). - Config — Site URL,
trailingSlash, Sanity integration, and env loading live inastro.config.mjs. Vite’sloadEnvis used forPUBLIC_*variables when the config is evaluated.
npm installat the repo root;npm run devfor the marketing site.- When changing Sanity schemas or bulk-editing content, run
npm run devinsidestudio-hack-michigan-/as well (or use the site’s/studioroute afterastro dev). - After schema changes, update GROQ usage and any page types in
src/as needed, then confirm/projects/and detail pages still build. - Regenerate Astro ambient types if needed:
npx astro sync.
npm run verifyThis runs format checks, ESLint, Stylelint, astro check, and a production build. If the build step fails on Sanity fetches, confirm env vars and network access to the dataset.
- Astro 5 — SSG, MDX, View Transitions /
ClientRouter - Three.js — Background canvas
- Sanity — Content API + Studio
- TypeScript
- @astrojs/mdx, @astrojs/sitemap
Thanks to the developers who lead this project:
- shrinkray - Shrinkray Interactive, a full-service creative software design, development, and maintenance company
- shumunovsolutions - Shumunov Solutions, a software development and consulting company
Partner studios who supported delivery are credited on the live site in the Website Development footer section (src/components/BuiltByRow.astro).
MIT — see LICENSE.
