Follow Conventional Commits:
<type>[optional scope]: <description>
Types:
feat— end-user visible new functionality or behavior changefix— end-user visible bug fixesrefactor— restructuring code without changing behaviorchore— dependency updates, config changes, i18n strings, other maintenanceci— GitHub Actions workflowsdocs— documentation only
Scopes: pretalx, sheets, opass. Omit scope if not listed here.
Examples:
feat: add session detail pagefix(pretalx): handle empty speaker responsechore: add English translations for venue page
Use kebab-case: add-session-page, fix-sponsor-logo
pnpm install # install dependencies
pnpm dev # start dev server
pnpm build # static generation (nuxt generate)
pnpm lint # ESLint (check only; append --fix to auto-fix)
pnpm typecheck # Vue type checkingESLint is the sole formatter — no Prettier. Run pnpm lint before committing to check for errors, and pnpm lint --fix to auto-fix formatting and lint issues. Fix formatting and lint errors in the same commit as the code change, not as a separate commit.
Auto-import scanning is disabled (imports: { scan: false } in nuxt.config.ts). Composables and utilities from Vue, Nuxt, and other libraries are still auto-imported, but project-local composables in composables/ are not. You must use explicit imports for those.
Use UnoCSS classes (Tailwind Wind4 preset). Do not use Tailwind CSS directly.
- UI strings go in
<i18n lang="yaml">blocks inside Vue SFCs - Page content goes in
content/{en,zh}/as Markdown files - Default locale is
zh(Traditional Chinese); always provide bothzhanden
Nitro server routes live in server/api/. External API responses should be cached using defineCachedFunction. Shared request/response types go in shared/types/ as Zod schemas.