Synaplan
기업을 위한 오픈소스 AI 플랫폼
무료 클리닉·봉사 프로그램을 위한 일정·시간·자격증명 알림, 영·스페인어 지원, 최대 25명 무료
Volunteer scheduling, hour tracking and credential reminders for free clinics and other volunteer programs, in English and Spanish. Free up to 25 active volunteers.
비즈니스TypeScript · CSSGitHub @envolvapp온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗The envolv.org marketing site — English at /, Spanish at /es, light or dark to
match the visitor's system setting. One landing page + a live-demo page + three
comparison pages (/compare/…) + the privacy policy + demo-request capture.
This is Workstream B of the Envolv roadmap (ROADMAP.md in the medvolunteer
repo). It is deliberately a separate repo — see DECISIONS.md.
npm install
npm run dev # http://localhost:3100
npm run build
npm run lint
Port 3100, not Next's default 3000 — 3000 is taken by another project on Sean's machine, and Next silently bumping itself to 3001 is a confusing way to find that out. Vercel ignores the flag and assigns its own port, so this only affects local dev.
Copy .env.example → .env.local. Set the same vars on the Vercel project.
| Var | Required | Purpose |
|---|---|---|
RESEND_API_KEY | yes | Sends the demo-request notification. Missing → the form returns a visible error rather than silently dropping the lead. |
RESEND_FROM_EMAIL | yes | Must be on a Resend-verified domain. envolv.org was verified 2026-08-26, so use [email protected]. |
DEMO_NOTIFY_EMAILS | yes | Comma-separated. Every demo request goes to all of them. Adding a founder = an env var edit, no code change. |
NOTION_TOKEN | recommended | Secret of the "envolv-www leads" Notion integration. Saves each demo request as a row in Website Leads. Missing → leads are email-only. |
NOTION_LEADS_DATA_SOURCE_ID | recommended | Data source id of the Website Leads database (c38d2ca0-…, see Vercel). |
RESEND_WEBHOOK_SECRET | for support@ | Signing secret of the Resend webhook that calls /api/inbound (Resend → Webhooks → the inbox.email.received one, whsec_…). |
RESEND_INBOX_API_KEY | for support@ | A full-access Resend key — reading a received message needs it. Separate from RESEND_API_KEY, which stays sending-only. |
SUPPORT_FORWARD_TO | no | Comma-separated; who gets support@ mail. Defaults to DEMO_NOTIFY_EMAILS. |
NEXT_PUBLIC_DEMO_URL | no | Base URL of the demo app that /demo sends visitors into. Defaults to https://envolv-demo.vercel.app. |
⚠️
NEXT_PUBLIC_DEMO_URLis the onlyNEXT_PUBLIC_*var here, and that is on purpose. In themedvolunteerrepo, build-time inlining ofNEXT_PUBLIC_*caused a production login outage — vars were saved to Vercel ~10h after the last build, so the deployed bundle never got them. Everything on this site that matters (Resend key, recipients) is read on the server at request time and never baked into the browser bundle. Keep it that way.That does not mean changes are instant: Vercel applies an env-var change only to deployments created after it. Change a var → Redeploy (Deployments → ⋯ → Redeploy), or the live site keeps the old value.
This repo is public (
envolvapp/envolv-www). Real addresses and keys live only in the Vercel project — never in.env.exampleor anywhere else here.
All copy that makes a claim — pricing, competitor figures, vertical list — lives
in lib/content.ts (and, for the comparison pages, lib/compare.ts), not scattered
through JSX. Pricing and positioning follow the founders' action plan of 2026-10-31:
one plan, priced in bands by active volunteers (anyone with a completed shift,
clock-in or logged hour in the past 12 months), unlimited admins on every paid band,
no feature gates, clinics as the lead audience. Competitor figures carry their
sources and the date they were checked (AS_OF, SOURCES). Change the decision,
change content.ts.
The site lists only what ships today (2026-10-30 — this replaced the "Soon"
badges). A roadmap feature is not on the site at all until it's live in the app;
when it lands, add it to PAID_FEATURES in content.ts (every paid band gets it).
The header comment of content.ts lists what was checked against the app and when.
Comparison pages (/compare/volgistics-alternative-for-clinics,
/compare/get-connected-alternative, /compare/envolv-vs-civic-champs, and the same
under /es) are one component, components/ComparePage.tsx, fed by lib/compare.ts.
Their price rows are computed from BANDS / PRICE_POINTS, so they can't drift from
the pricing section. Named competitors appear only in these dated, sourced
comparisons and the home page's comparison table (DECISIONS 2026-10-31). Re-check
every competitor figure, and bump AS_OF, whenever you touch them.
Both languages live in the same file. Every visible claim in content.ts is an
{ en, es } pair, and the interface copy (headings, buttons, form labels) is in
lib/copy.ts. Change a sentence in one language, change it in the other. Prices,
limits and seat counts are plain numbers, so they can't drift between languages.
The Spanish uses "tú", like the Envolv apps, and still needs a native speaker's read
(ROADMAP B6).
여기까지가 README 앞부분입니다. 나머지는 원문에서 읽을 수 있습니다. README 전문 보기 ↗