This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
frontendcritical PriorityID: nuxt4-nitro-shared-ssr-state-guardrails

Nuxt 4 Nitro Server Isolation, Shared Layer Contracts, and SSR State Hydration Guardrails

Enforces strict architectural boundaries across the Nuxt 4 app/ directory, Nitro v2 server engine, and shared/ directory. Eliminates cross-request state pollution, server-side credential leakage in SSR payload hydration, and un-isolated module-level singletons in persistent worker runtimes.

Prohibited Anti-Pattern: Cross-Request State Pollution via Module Singletons and Server Secrets Leaked in SSR Hydration

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Nuxt 4 Nitro Server Isolation, Shared Layer Contracts, and SSR State Hydration Guardrails - Enforces strict architectural boundaries across the Nuxt 4 app/ directory, Nitro v2 server engine, and shared/ directory. Eliminates cross-request state pollution, server-side credential leakage in SSR payload hydration, and un-isolated module-level singletons in persistent worker runtimes.
globs: app/**/*.{ts,vue}, server/**/*.{ts,js}, shared/**/*.{ts,js}, nuxt.config.ts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/nuxt4-nitro-shared-ssr-state-guardrails"
---

# Nuxt 4 Nitro Server Isolation, Shared Layer Contracts, and SSR State Hydration Guardrails

> **Severity**: CRITICAL | **Category**: frontend
> **Anti-Pattern Warning**: Cross-Request State Pollution via Module Singletons and Server Secrets Leaked in SSR Hydration

## System Constraints
You are a Principal Software Architect enforcing enterprise-grade Nuxt 4 and Nitro v2 conventions. Enforce the strict physical partition of the app/, server/, and shared/ directories. Eliminate cross-request memory leaks, prevent client exposure of server-side secrets during hydration, and enforce deterministic, context-isolated execution across all runtime targets (Node.js, Cloudflare Workers, Bun).

## Strict Guidelines
- Engineers MUST ALWAYS isolate all client-facing UI logic, Vue components, layouts, pages, and client composables inside the 'app/' directory conforming to Nuxt 4 directory topology.
- Engineers MUST NEVER declare mutable variables (e.g., 'let userSession', 'const cache = new Map()') at module scope in Nitro event handlers ('server/api/**', 'server/routes/**') or SSR composables, as persistent Node/Edge worker runtimes share module scope across distinct user requests.
- Engineers MUST ALWAYS store request-scoped data on 'event.context' inside Nitro server middleware and routes, rather than relying on global stores or ambient singletons.
- Code inside 'shared/' MUST ALWAYS be deterministic, side-effect-free, and runtime-agnostic (pure TypeScript interfaces, Zod validation schemas, pure transformation functions).
- Engineers MUST NOT import Node.js built-ins ('fs', 'crypto', 'path'), Nitro utilities ('getCookie', 'readBody'), or server-only environmental secrets into 'shared/' or 'app/' code.
- Services MUST sanitize data returned by Nitro route handlers to ensure sensitive server fields (passwords, tokens, database IDs, private flags) are not serialized into the SSR '__NUXT_DATA__' hydration payload.
- Components NEVER use ref() or reactive() outside setup() or script setup at top-level module scope; SSR-synchronized state MUST ALWAYS use 'useState<T>(key, init)' with a globally unique key.
- Code MUST ensure that any state injected into 'useState()' is JSON-serializable and free of non-serializable objects (DOM nodes, class instances with private state, streams, functions) to prevent SSR hydration serialization crashes.

## Bad vs Good Implementations
### Cross-Request State Pollution in Nitro Handler vs Context-Isolated Storage

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Module-scope variables in long-running Nitro workers (Node, Cloudflare Workers, Fastly) persist across invocations. A concurrent or subsequent request from a different user will read or overwrite 'currentUserCache', leading to critical data leakage and authorization breaches.
```typescript
// server/api/user-profile.get.ts
import { defineEventHandler, getQuery } from 'h3';

// ANTI-PATTERN: Global module-level mutable state leaks across requests in persistent workers
let currentUserCache: { id: string; role: string } | null = null;

export default defineEventHandler(async (event) => {
  const query = getQuery(event);
  
  if (query.userId) {
    // Mutating module-level variable will leak User A's data to User B on concurrent requests
    currentUserCache = await fetchUserFromDb(String(query.userId));
  }

  return { user: currentUserCache };
});
```

#### Production Standard (Correct)
> **Standard**: The handler eliminates module-level variables completely. State validation and shaping leverage isomorphic schemas from the 'shared/' layer, and any intermediate contextual data is isolated to the immutable-per-request 'event.context'.
```typescript
// server/api/user-profile.get.ts
import { defineEventHandler, getQuery, createError } from 'h3';
import { UserProfileSchema, type UserProfile } from '~~/shared/types/user';

export default defineEventHandler(async (event): Promise<{ user: UserProfile }> => {
  const query = getQuery(event);
  const userId = query.userId ? String(query.userId) : null;

  if (!userId) {
    throw createError({ statusCode: 400, statusMessage: 'User ID is required' });
  }

  // Request-scoped retrieval bound to event context or isolated storage
  const rawUser = await fetchUserFromDb(userId);
  
  // Parse and strip private server fields using isomorphic shared schema
  const user = UserProfileSchema.parse(rawUser);

  // Cache within request lifetime using event context if needed across internal plugins
  event.context.user = user;

  return { user };
});
```

### Shared Directory Isolation and SSR Hydration State Safety

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Importing Node-specific packages or server configuration into 'shared/' breaks client compilation and exposes private keys. Declaring a Vue 'ref' at module level inside a composable leaks client state across server-rendered requests.
```typescript
// shared/utils/auth.ts
// ANTI-PATTERN: Leaking server runtime dependency and un-hydrated singleton into shared layer
import { useRuntimeConfig } from '#imports';
import jwt from 'jsonwebtoken'; // Node-native dependency breaks client build!

export const verifySessionToken = (token: string) => {
  const config = useRuntimeConfig();
  // Leaks private server secret into client bundle if imported from app/
  return jwt.verify(token, config.jwtSecret);
};

// app/composables/useSession.ts
// ANTI-PATTERN: Client-side ref used across SSR boundary without useState
import { ref } from 'vue';
const globalAuthToken = ref<string | null>(null); // Shared across SSR renders in Node runtime

export const useSession = () => {
  return { globalAuthToken };
};
```

#### Production Standard (Correct)
> **Standard**: The 'shared/' code remains pure TypeScript and platform-agnostic, usable in both browser and Nitro. The composable strictly uses Nuxt's 'useState' primitive inside the factory function to ensure that SSR request isolation is preserved and correctly serialized into the hydration payload.
```typescript
// shared/schemas/session.ts
// GOOD: Pure, universal runtime validation with no ambient secrets or platform APIs
import { z } from 'zod';

export const SessionPayloadSchema = z.object({
  userId: z.string().uuid(),
  role: z.enum(['admin', 'member', 'guest']),
  expiresAt: z.number().int()
});

export type SessionPayload = z.infer<typeof SessionPayloadSchema>;

// app/composables/useSession.ts
// GOOD: Safe SSR state hydration using useState with scoped key
import type { SessionPayload } from '~~/shared/schemas/session';

export const useSession = () => {
  // useState guarantees isolation across SSR requests and synchronizes payload to client
  const session = useState<SessionPayload | null>('user-session', () => null);

  const setSession = (payload: SessionPayload) => {
    session.value = payload;
  };

  const clearSession = () => {
    session.value = null;
  };

  return {
    session: readonly(session),
    setSession,
    clearSession
  };
};
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Nuxt 4 Nitro Server Isolation, Shared Layer Contracts, and SSR State Hydration Guardrails

Nuxt 4 Nitro Server Isolation, Shared Layer Contracts, and SSR State Hydration Guardrails defines an industrial-grade behavioral standard for frontend engineering. Enforces strict architectural boundaries across the Nuxt 4 app/ directory, Nitro v2 server engine, and shared/ directory. Eliminates cross-request state pollution, server-side credential leakage in SSR payload hydration, and un-isolated module-level singletons in persistent worker runtimes. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Cross-Request State Pollution via Module Singletons and Server Secrets Leaked in SSR Hydration Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftCross-Request State Pollution via Module Singletons and Server Secrets Leaked in SSR HydrationCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS isolate all client-facing UI logic, Vue components, layouts, pages, and client composables inside the 'app/' directory conforming to Nuxt 4 directory topology.

Engineers MUST ALWAYS isolate all client-facing UI logic, Vue components, layouts, pages, and client composables inside the 'app/' directory conforming to Nuxt 4 directory topology.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NEVER declare mutable variables (e.g., 'let userSession', 'const cache = new Map()') at module scope in Nitro event handlers ('server/api/**', 'server/routes/**') or SSR composables, as persistent Node/Edge worker runtimes share module scope across distinct user requests.

Engineers MUST NEVER declare mutable variables (e.g., 'let userSession', 'const cache = new Map()') at module scope in Nitro event handlers ('server/api/**', 'server/routes/**') or SSR composables, as persistent Node/Edge worker runtimes share module scope across distinct user requests.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST ALWAYS store request-scoped data on 'event.context' inside Nitro server middleware and routes, rather than relying on global stores or ambient singletons.

Engineers MUST ALWAYS store request-scoped data on 'event.context' inside Nitro server middleware and routes, rather than relying on global stores or ambient singletons.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Code inside 'shared/' MUST ALWAYS be deterministic, side-effect-free, and runtime-agnostic (pure TypeScript interfaces, Zod validation schemas, pure transformation functions).

Code inside 'shared/' MUST ALWAYS be deterministic, side-effect-free, and runtime-agnostic (pure TypeScript interfaces, Zod validation schemas, pure transformation functions).

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Engineers MUST NOT import Node.js built-ins ('fs', 'crypto', 'path'), Nitro utilities ('getCookie', 'readBody'), or server-only environmental secrets into 'shared/' or 'app/' code.

Engineers MUST NOT import Node.js built-ins ('fs', 'crypto', 'path'), Nitro utilities ('getCookie', 'readBody'), or server-only environmental secrets into 'shared/' or 'app/' code.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Services MUST sanitize data returned by Nitro route handlers to ensure sensitive server fields (passwords, tokens, database IDs, private flags) are not serialized into the SSR '__NUXT_DATA__' hydration payload.

Services MUST sanitize data returned by Nitro route handlers to ensure sensitive server fields (passwords, tokens, database IDs, private flags) are not serialized into the SSR '__NUXT_DATA__' hydration payload.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
7

Components NEVER use ref() or reactive() outside setup() or script setup at top-level module scope

Components NEVER use ref() or reactive() outside setup() or script setup at top-level module scope; SSR-synchronized state MUST ALWAYS use 'useState<T>(key, init)' with a globally unique key.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
8

Code MUST ensure that any state injected into 'useState()' is JSON-serializable and free of non-serializable objects (DOM nodes, class instances with private state, streams, functions) to prevent SSR hydration serialization crashes.

Code MUST ensure that any state injected into 'useState()' is JSON-serializable and free of non-serializable objects (DOM nodes, class instances with private state, streams, functions) to prevent SSR hydration serialization crashes.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Nuxt 4 Nitro Server Isolation, Shared Layer Contracts, and SSR State Hydration Guardrails critical for AI coding assistants?

Enforces strict architectural boundaries across the Nuxt 4 app/ directory, Nitro v2 server engine, and shared/ directory. Eliminates cross-request state pollution, server-side credential leakage in SSR payload hydration, and un-isolated module-level singletons in persistent worker runtimes. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Cross-Request State Pollution via Module Singletons and Server Secrets Leaked in SSR Hydration) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

Related FRONTEND Rules

View all rules →
frontend
119

SolidStart 1.0 Server Functions & Async Boundaries Production Standard

SolidStart 1.0 relies on the Vinxi bundler to split `server$` closures into independent HTTP POST RPC endpoints. Direct lexical closure over client signals within `server$` scopes or failure to demarcate async boundaries with `<Suspense>` causes silent serialization failures, client-bundle secret leaks, and SSR hydration mismatches. Enforcing strict parameter passing, runtime input validation, and Solid async primitives maintains security and fine-grained reactivity across network boundaries.

frontend
119

Astro 5 Actions & Content Layer Production Standard

Enforces strict type safety and architectural correctness for Astro 5 Server Actions and the zero-waterfall Content Layer API. Prevents runtime contract mismatches, hydration mismatches, and unhandled mutation exceptions across dynamic and prerendered boundaries. Failure to follow these patterns leads to silent data fetching waterfalls, build-time cache corruptions, and unhandled server action exceptions.

frontend
51

Nuxt 4 Nitro Server Engine & Shared Directory Production Standard

Nuxt 4 enforces strict boundary segregation between client UI in the app/ directory, backend endpoints in server/, and universal contracts in shared/. Violating cross-boundary isolation or maintaining module-scoped state in Nitro server handlers causes catastrophic cross-request data corruption and hydration mismatches under concurrent production traffic. Architects must enforce request-isolated H3 event contexts, universal serialization schemas, and strict path-alias boundaries.

1 Rule in Stack

Nuxt