Workflow & Conventions
How to go from an idea to a merged pull request.
The loop
-
Open or pick an issue. For public API changes, agree on the design in the issue first.
-
Branch from
main:fix/slug-uniqueness,feat/date-range-bounds,docs/hooks-examples. -
Write a failing test that captures the bug or the new behavior.
-
Implement the change.
-
Add a changeset if a published package changed:
Terminalpnpm changesetPick the packages, the bump (
patchfor fixes,minorfor features,majorfor breaking changes), and write one or two sentences for the changelog, written for users of the package. -
Update the docs in
apps/docs/contentwhen behavior or options change. -
Run the checks locally:
Terminalpnpm typecheck && pnpm lint && pnpm test:unit -
Open a pull request against
main.
Changesets are required
The Changeset Check workflow runs pnpm changeset status --since origin/main on every pull request. A change to nextjs-cms, create-nextjs-cms, @nextjscms/translations, or a plugin without a changeset fails it. Changes that only touch apps/cms (ignored in .changeset/config.json), the docs, or tests don't need one; add an empty changeset (pnpm changeset --empty) if the check complains.
Code style
Prettier and ESLint enforce most of it:
- 4-space indentation, 120-character lines.
- Single quotes, no semicolons, trailing commas.
- Imports sorted automatically; Tailwind classes sorted.
Beyond formatting:
- Match the surrounding code. Comment density, naming, and patterns should look like the file you're in.
- Validate at the edges. Field and section helpers validate their options with Zod
strictObjectso typos fail loudly at load time. Follow the same pattern for new options. - Server-only stays server-only. Modules that touch the database, the filesystem, or sharp must never be reachable from client components. Environment-neutral code (validators, conditional-rule evaluation, inline-image sizing) lives in leaf modules with type-only imports.
- User-facing strings are translatable. Use
getString(key, language)on the server anduseI18n()in the admin, and add keys to the English base dictionary. - No silent failures. If a user's config can't work, throw with a message that names the section and field.
Commit messages
Short, imperative, and specific: Support 'now' as DateField default, Fix slug uniqueness check on locale submit. Explain the why in the body when it isn't obvious.
Pull request checklist
- Tests cover the change (unit, and integration if SQL is involved).
-
pnpm typecheck,pnpm lint, andpnpm test:unitpass. - A changeset describes user-visible changes.
- Developer docs are updated for new or changed options.
- No edits to generated files (
create-nextjs-cms/templates,dynamic-schemas,_section-hot-reload.js).