<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vildanden</title>
    <description>The latest articles on DEV Community by Vildanden (@vildandenai).</description>
    <link>https://dev.to/vildandenai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4128566%2Faf126918-50e5-4f9d-9586-c96c758ecb77.png</url>
      <title>DEV Community: Vildanden</title>
      <link>https://dev.to/vildandenai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vildandenai"/>
    <language>en</language>
    <item>
      <title>Scoped Cursor Rules for Next.js App Router: Conventions, Server Actions, and Security</title>
      <dc:creator>Vildanden</dc:creator>
      <pubDate>Wed, 16 Sep 2026 20:04:57 +0000</pubDate>
      <link>https://dev.to/vildandenai/scoped-cursor-rules-for-nextjs-app-router-conventions-server-actions-and-security-413l</link>
      <guid>https://dev.to/vildandenai/scoped-cursor-rules-for-nextjs-app-router-conventions-server-actions-and-security-413l</guid>
      <description>&lt;p&gt;A Cursor rule that applies to every file is easy to write and surprisingly easy to ignore. In a Next.js App Router project, a convention for &lt;code&gt;app/&lt;/code&gt; is useful while editing route code, a server-action reminder belongs near mutations, and a security checklist should be visible at server boundaries. Those are different contexts, so they should not be one oversized instruction file.&lt;/p&gt;

&lt;p&gt;This tutorial builds three small &lt;code&gt;.mdc&lt;/code&gt; rules with different scopes. The goal is not to make an agent autonomous. The goal is to put the right reminder beside the code where a mistake would be expensive.&lt;/p&gt;

&lt;p&gt;If you want the background model first, see &lt;a href="https://dev.to/vildandenai/a-minimal-agentsmd-and-cursor-rules-setup-for-nextjs-app-router-49cc"&gt;A Minimal AGENTS.md and Cursor Rules Setup for Next.js App Router&lt;/a&gt;. This article takes the narrower, hands-on path: designing and installing the Cursor rules themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we are building
&lt;/h2&gt;

&lt;p&gt;Assume a conventional App Router repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  dashboard/page.tsx
  settings/actions.ts
  api/reports/route.ts
components/
lib/
.cursor/
  rules/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will add:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;app-conventions.mdc&lt;/code&gt; for route and component conventions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;server-actions.mdc&lt;/code&gt; for mutations and server-side data access.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;security-boundaries.mdc&lt;/code&gt; for authentication, authorization, validation, and secret handling.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first two rules are scoped to relevant paths. The security rule is deliberately broader, because a secret or authorization mistake can happen in a route, a library, or a component boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create the rules directory
&lt;/h2&gt;

&lt;p&gt;From the project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .cursor/rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the project already has &lt;code&gt;.cursor/rules/&lt;/code&gt;, inspect the existing files before adding new ones. Keep one responsibility per rule. A rule should be small enough that a teammate can review it in one sitting.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Add the App Router conventions rule
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;.cursor/rules/app-conventions.mdc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Next.js&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;App&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Router&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;React&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;conventions"&lt;/span&gt;
&lt;span class="na"&gt;globs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;app/**/*.{ts,tsx},components/**/*.{ts,tsx}"&lt;/span&gt;
&lt;span class="na"&gt;alwaysApply&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# App Router conventions&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Keep route UI, loading states, and error boundaries close to their route under &lt;span class="sb"&gt;`app/`&lt;/span&gt;.
&lt;span class="p"&gt;-&lt;/span&gt; Prefer Server Components by default.
&lt;span class="p"&gt;-&lt;/span&gt; Add &lt;span class="sb"&gt;`"use client"`&lt;/span&gt; only for hooks, browser APIs, or interactive event handlers.
&lt;span class="p"&gt;-&lt;/span&gt; Keep Client Components small and pass serializable props from the server.
&lt;span class="p"&gt;-&lt;/span&gt; Reuse the repository's existing components and data-access patterns before creating new ones.
&lt;span class="p"&gt;-&lt;/span&gt; Use the project's existing path layout; if it uses &lt;span class="sb"&gt;`src/`&lt;/span&gt;, update this rule's globs.
&lt;span class="p"&gt;-&lt;/span&gt; Prefer &lt;span class="sb"&gt;`next/link`&lt;/span&gt; and &lt;span class="sb"&gt;`next/image`&lt;/span&gt; for internal links and images.
&lt;span class="p"&gt;-&lt;/span&gt; Preserve the project's loading, empty, and error states when changing a route.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is one intentional detail here: this rule does not say “always use Server Components.” It says to start there and name the exceptions. A settings form or a browser-only widget may need the client. A scoped rule should guide judgment, not prohibit valid architecture.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;globs&lt;/code&gt; line also makes the rule easier to reason about. Editing &lt;code&gt;components/&lt;/code&gt; should show component conventions; editing a documentation file should not. If your application lives at &lt;code&gt;src/app&lt;/code&gt;, use patterns such as &lt;code&gt;src/app/**/*.{ts,tsx}&lt;/code&gt; instead.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Keep the frontmatter keys exactly as your Cursor version expects. The &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;globs&lt;/code&gt;, and &lt;code&gt;alwaysApply&lt;/code&gt; fields are the useful minimum for a scoped project rule.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Add the server actions rule
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;.cursor/rules/server-actions.mdc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Server Actions, route handlers, and server-side data access&lt;/span&gt;
&lt;span class="na"&gt;globs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;app/**/*.{ts,tsx},lib/**/*.{ts,tsx}"&lt;/span&gt;
&lt;span class="na"&gt;alwaysApply&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Server-side mutations and data&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Treat every Server Action and Route Handler as a public server boundary.
&lt;span class="p"&gt;-&lt;/span&gt; Validate form data, JSON, params, and search params before using them.
&lt;span class="p"&gt;-&lt;/span&gt; Check authentication and authorization on the server; client checks are only UX.
&lt;span class="p"&gt;-&lt;/span&gt; Keep database and secret-bearing calls in server-only modules.
&lt;span class="p"&gt;-&lt;/span&gt; Return a safe result shape; do not send stack traces or private fields to the client.
&lt;span class="p"&gt;-&lt;/span&gt; Revalidate the specific path or tag affected by a successful write.
&lt;span class="p"&gt;-&lt;/span&gt; Make mutations idempotent where retries are possible.
&lt;span class="p"&gt;-&lt;/span&gt; Add focused tests for authorization and invalid input when changing a mutation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key phrase is &lt;strong&gt;public server boundary&lt;/strong&gt;. A Server Action is called from a UI, but it is still a server entry point. Anyone who can reach the application may attempt to invoke the endpoint, so hiding the button is not an authorization mechanism.&lt;/p&gt;

&lt;p&gt;For example, a mutation should validate both its input and the current user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;revalidatePath&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;requireUser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/lib/auth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;updateProfile&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/lib/data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;profileSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;requireUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;profileSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;displayName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;updateProfile&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;revalidatePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/settings&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example is intentionally boring. It establishes the boundary, narrows untrusted data, uses the authenticated user rather than a user ID supplied by the browser, and revalidates only the affected route.&lt;/p&gt;

&lt;p&gt;Do not copy this example blindly. Match the repository's existing schema, auth, data-access, and error-handling libraries. The rule is there to make those decisions visible while the file is open.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Add the security boundaries rule
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;.cursor/rules/security-boundaries.mdc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Security checks for Next.js server and client boundaries&lt;/span&gt;
&lt;span class="na"&gt;globs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;**/*.{ts,tsx,js,jsx}"&lt;/span&gt;
&lt;span class="na"&gt;alwaysApply&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Security boundaries&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Never place secrets, private tokens, or privileged SDK calls in Client Components.
&lt;span class="p"&gt;-&lt;/span&gt; Use &lt;span class="sb"&gt;`NEXT_PUBLIC_*`&lt;/span&gt; only for values that are safe to expose in the browser.
&lt;span class="p"&gt;-&lt;/span&gt; Enforce authorization on the server for every protected read and mutation.
&lt;span class="p"&gt;-&lt;/span&gt; Treat request data, cookies, headers, URL params, and third-party responses as untrusted.
&lt;span class="p"&gt;-&lt;/span&gt; Avoid rendering user-provided HTML; if HTML is required, use the project's reviewed sanitizer.
&lt;span class="p"&gt;-&lt;/span&gt; Do not log passwords, tokens, session cookies, or sensitive personal data.
&lt;span class="p"&gt;-&lt;/span&gt; Return generic client-facing errors and keep diagnostic details in protected server logs.
&lt;span class="p"&gt;-&lt;/span&gt; Never commit &lt;span class="sb"&gt;`.env`&lt;/span&gt; files, credentials, or generated secret-bearing output.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This rule is &lt;code&gt;alwaysApply: true&lt;/code&gt; because security concerns cross directory boundaries. Its job is to catch the dangerous category error: trusting a value because it came from a UI, a cookie, a hidden field, or a third-party API.&lt;/p&gt;

&lt;p&gt;It is still not a security review. Keep code review, dependency updates, CI checks, and your application's threat model. A rule can remind an agent to check authorization; it cannot prove that the authorization policy is correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Install the free Vildanden sample instead
&lt;/h2&gt;

&lt;p&gt;If you prefer ready-to-copy files, download the free Vildanden Next.js + React sample:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://vildanden.gumroad.com/l/xphax" rel="noopener noreferrer"&gt;https://vildanden.gumroad.com/l/xphax&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download and extract the sample outside your application first.&lt;/li&gt;
&lt;li&gt;Copy or merge &lt;code&gt;AGENTS.md&lt;/code&gt; and &lt;code&gt;CLAUDE.md&lt;/code&gt; into the repository root; preserve useful project-specific guidance.&lt;/li&gt;
&lt;li&gt;Copy the &lt;code&gt;.cursor/rules/*.mdc&lt;/code&gt; files into your project's &lt;code&gt;.cursor/rules/&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Change every glob that does not match your layout, especially &lt;code&gt;src/app&lt;/code&gt;, monorepo package paths, or custom component directories.&lt;/li&gt;
&lt;li&gt;Reopen the repository in Cursor so the project rules are loaded.&lt;/li&gt;
&lt;li&gt;Make a small test edit in &lt;code&gt;app/&lt;/code&gt;, a server mutation, and a security-sensitive file. Confirm the relevant rules appear in the editor context.&lt;/li&gt;
&lt;li&gt;Run the repository's normal typecheck, lint, and focused tests.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The files are configuration, not a runtime package: there is nothing to add to &lt;code&gt;package.json&lt;/code&gt;, no production dependency, and no database migration.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick review checklist
&lt;/h2&gt;

&lt;p&gt;Before committing your rules, check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does every scoped rule match the directories your project actually uses?&lt;/li&gt;
&lt;li&gt;Is any rule repeating a longer instruction file word for word?&lt;/li&gt;
&lt;li&gt;Are server mutations told to validate input and authorize the current user?&lt;/li&gt;
&lt;li&gt;Are secrets and privileged calls kept out of Client Components?&lt;/li&gt;
&lt;li&gt;Does the guidance preserve local conventions instead of forcing a new architecture?&lt;/li&gt;
&lt;li&gt;Can a teammate understand the rule without opening another five files?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a rule keeps producing irrelevant suggestions, narrow its glob or split it by responsibility. If an important reminder is missing at a boundary, add one concrete line rather than another page of principles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want more stacks and rules?
&lt;/h2&gt;

&lt;p&gt;The free sample covers Next.js + React. The optional Vildanden pack adds more stacks, additional rule coverage, and more prompt templates:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://vildanden.gumroad.com/l/daody" rel="noopener noreferrer"&gt;https://vildanden.gumroad.com/l/daody&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start with the free sample, adapt the globs to your repository, and keep only the guidance that reflects how your team actually ships.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclosure:&lt;/strong&gt; This tutorial was created for Vildanden and links to Vildanden downloads. The examples are educational defaults, not a substitute for your project's review and security practices.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>cursor</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A Minimal AGENTS.md and Cursor Rules Setup for Next.js App Router</title>
      <dc:creator>Vildanden</dc:creator>
      <pubDate>Wed, 16 Sep 2026 19:02:24 +0000</pubDate>
      <link>https://dev.to/vildandenai/a-minimal-agentsmd-and-cursor-rules-setup-for-nextjs-app-router-49cc</link>
      <guid>https://dev.to/vildandenai/a-minimal-agentsmd-and-cursor-rules-setup-for-nextjs-app-router-49cc</guid>
      <description>&lt;p&gt;Coding agents do not know the conventions of a Next.js codebase unless the repository tells them. Without that context, a new session can introduce a second router, move data fetching into the browser, expose an environment variable, or ignore the project’s existing naming patterns.&lt;/p&gt;

&lt;p&gt;A large instruction dump is not the answer. A small set of scoped rules is easier to review, easier to keep current, and more likely to be followed.&lt;/p&gt;

&lt;p&gt;This guide shows a practical baseline for Next.js App Router projects using &lt;code&gt;AGENTS.md&lt;/code&gt;, &lt;code&gt;CLAUDE.md&lt;/code&gt;, and Cursor project rules. The free Vildanden sample contains the complete files described here.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four-layer setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;AGENTS.md&lt;/code&gt;: the tool-neutral baseline
&lt;/h3&gt;

&lt;p&gt;Keep the durable engineering decisions in a root &lt;code&gt;AGENTS.md&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the App Router and do not invent a parallel &lt;code&gt;pages/&lt;/code&gt; tree.
The important part is not the filename alone. The file should describe the repository’s actual architecture, not an idealized rewrite of it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;code&gt;CLAUDE.md&lt;/code&gt;: a short Claude Code pointer
&lt;/h3&gt;

&lt;p&gt;A lean &lt;code&gt;CLAUDE.md&lt;/code&gt; can point Claude Code to the baseline and add only tool-specific habits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# CLAUDE.md&lt;/span&gt;

Treat &lt;span class="sb"&gt;`AGENTS.md`&lt;/span&gt; as the source of truth for this repository.
&lt;span class="p"&gt;
-&lt;/span&gt; Scan neighboring files before adding a new pattern.
&lt;span class="p"&gt;-&lt;/span&gt; Prefer Server Components unless hooks or browser APIs require the client.
&lt;span class="p"&gt;-&lt;/span&gt; Match the package manager and scripts in &lt;span class="sb"&gt;`package.json`&lt;/span&gt;.
&lt;span class="p"&gt;-&lt;/span&gt; Validate mutations and run focused checks for changed paths.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avoid duplicating the entire instruction set in two files. Duplication drifts.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Cursor &lt;code&gt;.mdc&lt;/code&gt; rules: scope the reminders
&lt;/h3&gt;

&lt;p&gt;Cursor project rules can make the same guidance visible at the right time. A rule for server actions and data access does not need to apply to every Markdown file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Server&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;actions,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;route&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;handlers,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fetching"&lt;/span&gt;
&lt;span class="na"&gt;globs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;**/app/**/*.{ts,tsx},**/lib/**/*.{ts,tsx}"&lt;/span&gt;
&lt;span class="na"&gt;alwaysApply&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

Use &lt;span class="sb"&gt;`alwaysApply: true`&lt;/span&gt; for genuinely global guidance such as security basics. Use globs for rules that are meaningful only in particular files. If the app uses &lt;span class="sb"&gt;`src/app`&lt;/span&gt;, update the patterns rather than blindly copying them.

&lt;span class="gu"&gt;### 4. Prompts: make the desired finish state explicit&lt;/span&gt;

A prompt template is useful when it asks for more than implementation. For a feature, request loading, empty, and error states, tests for risky behavior, and a final summary of files changed and verification steps. For a bug fix, request a root-cause explanation and a regression test when practical.

These prompts are optional. The project rules are the durable layer; prompts are task-level scaffolding.

&lt;span class="gu"&gt;## A 60-second install&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; Copy &lt;span class="sb"&gt;`AGENTS.md`&lt;/span&gt; and &lt;span class="sb"&gt;`CLAUDE.md`&lt;/span&gt; into the project root, or merge them with existing files.
&lt;span class="p"&gt;2.&lt;/span&gt; Copy the three &lt;span class="sb"&gt;`.mdc`&lt;/span&gt; files into &lt;span class="sb"&gt;`.cursor/rules/`&lt;/span&gt;.
&lt;span class="p"&gt;3.&lt;/span&gt; Adjust globs for &lt;span class="sb"&gt;`src/`&lt;/span&gt; layouts and local conventions.
&lt;span class="p"&gt;4.&lt;/span&gt; Reopen the project and confirm the rules appear in the tool.
&lt;span class="p"&gt;5.&lt;/span&gt; Run the project’s normal checks before trusting the result.

The sample has no runtime dependency and does not modify your application. It is a starting point, not a claim that three rules can replace CI, review, or security work.

&lt;span class="gu"&gt;## Download the sample&lt;/span&gt;

The free Next.js + React sample is available from Vildanden:

https://vildanden.gumroad.com/l/xphax

For a deeper pass on conventions, Server Actions, and security, see &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Scoped Cursor Rules for Next.js App Router&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://dev.to/vildandenai/scoped-cursor-rules-for-nextjs-app-router-conventions-server-actions-and-security-413l&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;.

For projects that also need Node/TypeScript API, Python FastAPI, and general-fullstack variants, the optional four-stack pack is here:

https://vildanden.gumroad.com/l/daody

&lt;span class="gs"&gt;**Disclosure:**&lt;/span&gt; This article describes a Vildanden sample and links to its free download and optional paid expansion.&lt;span class="sb"&gt;


&lt;/span&gt;&lt;span class="gh"&gt;# Data and mutations&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Validate mutation payloads at the server boundary.
&lt;span class="p"&gt;-&lt;/span&gt; Revalidate the specific path or tag after writes.
&lt;span class="p"&gt;-&lt;/span&gt; Treat request bodies and search parameters as untrusted.
&lt;span class="p"&gt;-&lt;/span&gt; Do not leak stack traces to production clients.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Prefer Server Components; use Client Components for hooks, events, and browser APIs.&lt;/li&gt;
&lt;li&gt;Keep shared UI in &lt;code&gt;components/&lt;/code&gt; and domain logic in &lt;code&gt;lib/&lt;/code&gt; (or the project’s existing equivalents).&lt;/li&gt;
&lt;li&gt;Validate external input at server boundaries.&lt;/li&gt;
&lt;li&gt;Keep secrets server-side and document required keys in &lt;code&gt;.env.example&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run the narrowest useful typecheck, lint, and tests before finishing.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>cursor</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
