Agentero
Connect your own Agent, keep research context in a local Vault. Seamlessly migrate from Zotero, read, understand, link, and reuse your research context.
AI translation
Create and join polls to vote and view results
AI summary · website content
ProductivityTypeScript · CSSGitHub @vomattOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Public voting platform. This repo is the Next.js 16 front end. App data (polls, ballots, comments, accounts) comes from vomatt-api; site content (settings, the sign-up terms) comes from Sanity. Editors use the Sanity Studio in vomatt-admin.
Browser ──► vomatt-web (Vercel) ──► vomatt-api (server-side only, Bearer token from httpOnly cookies)
│
└────────────► Sanity (published content, expired per change on publish)
pnpm-lock.yaml; corepack enable picks the version pinned in package.json)pnpm install
cp .env.example .env.local # then fill in the values, see below
pnpm dev
NEXT_PUBLIC_SANITY_PROJECT_ID / NEXT_PUBLIC_SANITY_DATASET.Run it locally (see its README; Postgres + Redis via docker compose up -d), then set
API_URL=http://localhost:8080 and SESSION_SECRET to the API's JWT_SECRET.
Sign-in codes are emailed; with email disabled locally, read the code from Redis
(otp:email:<address>).
| Variable | Required | Example | What it's for |
|---|---|---|---|
NEXT_PUBLIC_SANITY_PROJECT_ID | Yes | abc123de | Sanity project. Also used to allow Sanity CDN images. |
NEXT_PUBLIC_SANITY_DATASET | Yes | production | Sanity dataset. |
API_URL | Yes | https://api.vomatt.com | vomatt-api origin only — no path, no trailing slash. Called from the server only. |
SESSION_SECRET | Yes | 64 random chars | Must equal the API's JWT_SECRET. Used to verify access tokens. A mismatch signs everyone out on every request. Server-only; never prefix with NEXT_PUBLIC_. |
CLIENT_IP_SECRET | Production | 48 random chars | Same value as the API's CLIENT_IP_SECRET. Sent with each user's IP so the API's rate limits and OTP lockouts apply per user. Unset: the API sees every user as this server's IP, so one abuser can rate-limit or lock out everyone. Server-only; mark Sensitive. |
SITE_URL | Yes | https://vomatt.com | Public origin, no trailing slash. Used for metadata, Open Graph and canonical URLs; the site errors if it is missing. |
API_LOG | No | 1 | Logs each API request/response from the server. On by default in pnpm dev (0 silences it); off in deployments unless 1 (e.g. a Preview scoped to the dev branch, read in Vercel Runtime Logs). |
IOS_APP_IDS | No | ABCDE12345.com.vomatt.app | iOS universal links: comma-separated <TeamID>.<bundle ID> values served in /.well-known/apple-app-site-association, so /poll/<id> and /<username> links open the app. Unset: that file 404s and links stay on the web. Set it in Production (the domain in the app's applinks: entitlement). |
SANITY_REVALIDATE_SECRET |
Not needed (leave unset): DATABASE_URL, PAYLOAD_SECRET (Payload was removed);
SANITY_API_READ_TOKEN (the site reads only published content, without a token); SANITY_STUDIO_PREVIEW_ORIGIN (the Presentation
tool was removed);
NEXT_PUBLIC_API_URL (the followers/following sheet calls this site's own /api routes when it is
unset).
On vomatt-api, set at least JWT_SECRET (same value as SESSION_SECRET), CLIENT_IP_SECRET (same value as here), the database and
Redis settings, and email (EMAIL_ENABLED=true + SMTP) — sign-in is email-code only.
The browser never calls the API directly, so its CORS_ALLOWED_ORIGINS doesn't need this site.
next build), output directory and install command at their defaults.pnpm-lock.yaml is in the repo. Don't commit a
package-lock.json alongside it. Add ENABLE_EXPERIMENTAL_COREPACK=1 (all environments) so Vercel uses
the pnpm version pinned in package.json instead of picking one from the lockfile.SITE_URL = your production domain, API_URL = production API.SITE_URL can be the preview's domain, API_URL a staging API.SESSION_SECRET and CLIENT_IP_SECRET as Sensitive.Before the first production deploy, run through docs/release/release-checklist.md.
pnpm dev # dev server (Turbopack, port 3002)
pnpm build # production build
pnpm start:web # serve the production build locally
pnpm start # run through `vercel dev` (needs the Vercel CLI and a linked project)
pnpm lint # ESLint
pnpm test # Jest (tests in src/__tests__/)
pnpm test:watch # Jest in watch mode
pnpm test:coverage # Jest with coverage
pnpm exec jest <path> # one test file
pnpm exec tsc --noEmit # type-check
pnpm generate:openapi # regenerate openapi.json from the Zod schemas
| File | What's in it |
|---|---|
| DESIGN.md | Design tokens, type, UI building blocks, don'ts — read before UI work |
| PRODUCT.md | Users, brand, product principles |
| CLAUDE.md | Architecture notes: route groups, data layer, auth/token refresh, i18n |
| api-docs.json | vomatt-api contract (what the API serves at /v3/api-docs) |
| docs/release/ | Release checklist, API integration notes, open backend requests |
SESSION_SECRET doesn't match the API's
JWT_SECRET.//api/... — API_URL has a trailing slash or a path.SITE_URL is missing.| No |
| 48 random chars |
Production only. Lets vomatt-admin's Sanity Function expire just the changed Sanity content on publish (POST /api/revalidate); while set, Sanity content refreshes only hourly as a fallback. Same value as the function's SANITY_REVALIDATE_SECRET (npx sanity functions env add invalidate-tags SANITY_REVALIDATE_SECRET <value> in vomatt-admin). Outside Production (local dev, Previews, which the function never calls) edits show up within about a minute, set or not. |
NEXT_PUBLIC_SANITY_API_VERSION | No | 2025-08-08 | Sanity API version; defaults to 2025-08-08. |
NEXT_PUBLIC_ABOUT_URL | No | https://about.vomatt.com | The about site's origin, no trailing slash. /about and the legal pages redirect there, and the app's legal links point there. Defaults to https://about.vomatt.com. |