Skip to content
CodeAndBuild LogoCodeAndBuild

AI Coding

Write Cursor Rules That Keep a Next.js Repo Consistent

Add project rules for the App Router, server-only secrets, and file layout so an AI assistant follows the repo you actually have.

CodeAndBuild Team8 min read
  • Cursor
  • Next.js
  • Rules
  • AI Coding
On this page
  1. Put rules next to the code they govern
  2. Write rules as decisions
  3. A rule for secrets
  4. Keep the rules true
  5. A rule you should delete

An AI coding assistant will invent a pages router, a new UI library, and a public environment variable for a secret if you do not tell it how this repo works. Cursor rules are that note, checked in with the code. They are not a style sermon. A useful rule says where files go, which APIs this version of Next.js expects, and which mistakes the team has already made. A rule that restates the documentation of React will be ignored, or worse, followed instead of the local pattern.

Keep rules short enough that a person will still read them when they change. Point at real files. Name the things that are forbidden because they broke production, not because they are unfashionable. Update the rule in the same change that updates the convention. A rule that describes last quarter's folder layout is how the assistant confidently edits the wrong tree.

Put rules next to the code they govern

Project rules live in .cursor/rules as markdown files. Give each file a narrow job: routing, data, or secrets. A single RULE.md that covers the whole company will not be applied with any precision. Use a description a teammate understands, and globs so a rule about route handlers is in context when a route handler is open. Always-on rules should be the short list that is true in every file.

.cursor/rules/app-router.mdcmd
---
description: App Router conventions for this Next.js repo
globs: app/**/*.{ts,tsx}
alwaysApply: false
---

- This repo uses the App Router. Do not add pages/.tsx routes.
- Route params are a Promise. Await them.
- Read request data in Server Components or route handlers.
- Do not add a new UI kit. Use the components already in components/.

Write rules as decisions

Each bullet should be something a reviewer could check. "Be clean" is not checkable. "Do not put service-role keys in a file that starts with use client" is checkable. Prefer the positive form when it names a file, and the prohibition when the cost of the mistake is high. Three to seven bullets per file is enough. If you need more, you need a second rule file.

  • Name the framework version's sharp edge. On this codebase, params and searchParams are promises.
  • Name the folder for a new component, a new post, and a new route.
  • Name the environment variables that are allowed in the browser. Everything else is server-only.
  • Name the command that verifies a change, such as the production build, if the agent is expected to run it.

A rule for secrets

Assistants love to be helpful by inlining a key "just for the example." Forbid that in a rule that is always applied. Tell the assistant to read process.env on the server and to stop when the variable is missing, rather than inventing a fallback string that looks like a real token. Examples in blog posts can show the name of a variable. They should not show a value.

.cursor/rules/secrets.mdcmd
---
description: Secrets stay on the server
alwaysApply: true
---

- Never commit API keys, tokens, or connection strings.
- Never prefix a secret with NEXT_PUBLIC_.
- If a task needs a key that is not in the environment, stop and ask. Do not invent one.

Keep the rules true

  1. 01

    Add a rule when a mistake repeats

    The second time an assistant creates a pages router file, write the rule. The first time, just fix it.

  2. 02

    Link to an example file

    "Follow app/blog/[slug]/page.tsx" is more accurate than a paragraph about dynamic routes.

  3. 03

    Delete stale bullets

    A rule about a library you removed will be followed. Review rules when you review dependencies.

  4. 04

    Do not paste your whole style guide

    Formatting belongs in the formatter. Rules are for choices the formatter cannot see.

Rules do not replace review. They shift the assistant toward the repo you have so the review is about the behavior, not about a random file location. If a rule and the code disagree, fix one of them in the same pull request. Leaving both is how the next session "helpfully" rewrites the code back to the old rule.

A rule you should delete

"Always write clever, production-grade, future-proof code" will be followed as permission to add a factory, a new folder, and a dependency for a one-line fix. Replace it with the decision you actually mean. For a Next.js blog that stores posts in one module, the decision is: add a post object, do not invent a CMS, do not add an authentication library for a guide that is only documentation. Negative examples help. One line that says "do not create app/pages" prevents a class of edits that a paragraph about clean architecture does not. If you cannot explain a bullet to a new teammate in one sentence, it is not ready to be a rule. Read the file the way you would read a pull request. The rules that survive are the ones you would be glad the assistant saw.

More guides