Website for WWDC Watch Party Around India, built with React, TypeScript, Vite, and Tailwind CSS.
Install dependencies:
npm installRun the local dev server:
npm run devBuild for production:
npm run buildRun lint checks:
npm run lintThe site includes a landing page plus city pages:
/hyderabad/delhi/bangalore/mumbai/ahmedabad/surat/chennai/kozhikode/pune/nagpur
City routes are handled by /:citySlug in src/main.tsx.
The app is data-driven. UI components should import from src/data/city-events.ts:
import { cityEvents, getCityEventBySlug } from "../data/city-events";src/data/city-events.ts is the aggregator. It combines:
- base city event files (
src/data/city-events/<city>.ts) - tagged member assignments (
src/data/team-members.ts)
and produces:
teamMembersfor each city pagespeakersfor each city pagevenueSponsorsfor the homepage
Edit the matching file in src/data/city-events/:
ahmedabad.tsbangalore.tschennai.tsdelhi.tshyderabad.tskozhikode.tsmumbai.tssurat.tspune.tsnagpur.ts
Each file exports one CityEvent object.
Common fields:
slug: URL segment, for examplehyderabadfor/hyderabadaliases: misspellings or legacy slugs to auto-redirectcity,chapterNamedate,time,startDate,endDatevenue,address,structuredAddress,location,mapUrllumaUrl(optional): when missing, register buttons fall back tomapUrlsponsorName,sponsorLogo,sponsorDescription,sponsorWebsitegradientdescriptionhighlightsagenda
Use ISO 8601 with +05:30 for schema dates:
startDate: "2026-06-09T19:00:00+05:30";
endDate: "2026-06-10T00:30:00+05:30";City team members and speakers are assigned in src/data/team-members.ts.
Each profile can define cityAssignments with tags:
cityAssignments: [
{ city: "hyderabad", role: "Organizer", kind: "team" },
{
city: "hyderabad",
role: "Speaker",
kind: "speaker",
sessionTitle: "What is new in SwiftUI",
sessionDescription: "A quick walkthrough of key WWDC updates.",
tags: ["SwiftUI", "WWDC26"],
},
];Rules:
citymust match the city slug (for examplehyderabad,bangalore)kinddefaults toteamwhen omitted- no cap on number of members per city
- one person can appear in multiple cities
- cards show assignment tags (
City,Type,Role, custom tags)
City page sections are generated automatically:
{chapterName} Team Members{chapterName} Speakers(only when speaker assignments exist)
These sections are auto-generated from data:
Register Now: usescityEvents; card logo uses sponsor logo when available, else chapter logoVenue Sponsors: usesvenueSponsorsderived from city event sponsor fields
City page register CTAs:
- top-right action button
- registration card button
Behavior:
- if
lumaUrlexists, CTA points to Luma - if
lumaUrlis missing, CTA points tomapUrl
JSON-LD is generated in src/components/event-structured-data.tsx from city event data.
Keep these fields accurate:
startDateendDatevenuestructuredAddresslumaUrlormapUrldescriptionchapterName
Reference:
- Add assets under
src/assets/as needed. - Create
src/data/city-events/<city>.ts. - Export a
CityEventobject. - Import and include it in
src/data/city-events.ts. - Add
aliasesif needed. - Add member tags in
src/data/team-members.tsusingcityAssignments. - Run
npm run lintandnpm run build.
Clean URLs work with fallback files:
src/main.tsxpublic/404.htmlindex.htmlpublic/CNAME
src/components/register-now.tsxsrc/components/sponsors.tsxsrc/components/city-event-page.tsxsrc/components/event-structured-data.tsxsrc/data/city-events.tssrc/data/city-events/types.tssrc/data/team-members.ts