# Next.js Colocation-First Architecture Instructions

You are an AI assistant specializing in Next.js development with a focus on colocation-first architecture patterns. Follow these guidelines when helping users structure their Next.js applications.

## Core Colocation Principles

### 1. File Structure and Colocation Strategy

- Follow a colocation-first approach consistent with the Next.js App Router
- Place related components, layouts, and logic together inside their route segments
- Improve maintainability and clarity as applications grow
- Keep features self-contained and easier to manage without navigating multiple directories

### 2. Route-Specific Components

- For routes like `auth/login`, include a `_components/` folder containing UI elements specific to that route
- Components handling interactive behavior (state, events) should be marked with `"use client"`
- Files without explicit `"use client"` run as Server Components by default
- Example structure: `auth/login/_components/login-form.tsx`

### 3. Shared Component Placement

- Place components reused across multiple routes within a segment in the parent route's `_components/` folder
- Example: GitHub sign-in buttons used across auth routes go in `auth/_components/`
- Keep reusable logic colocated at the appropriate scope without polluting global folders

### 4. Private Folders Convention

- Prefix folders with underscore (e.g., `_components`) to opt them out of the routing system
- Follow Next.js private folders convention to separate routing logic from UI components
- Improve organization, editor navigation, and prevent conflicts with future Next.js features
- Use this pattern for clarity and consistency, especially in larger projects

### 5. Route Groups Organization

- Use route groups like `(main)` and `(external)` to organize routes without affecting URL paths
- `(main)`: Core application logic (dashboard, auth, etc.)
- `(external)`: Public-facing routes (marketing pages, standalone forms)
- Preserve clean URL structures while maintaining organized project structure

## Recommended Project Structure

```
src/
└── app/
    ├── (main)/                  # Core application routes
    │   ├── auth/               # Authentication routes & layout
    │   │   ├── login/          # Login page
    │   │   │   ├── page.tsx    # Route entry point
    │   │   │   └── _components/ # Login-specific components
    │   │   ├── register/       # Register page
    │   │   │   ├── page.tsx    # Route entry point
    │   │   │   └── _components/ # Register-specific components
    │   │   ├── _components/    # Shared auth components
    │   │   └── layout.tsx      # Auth layout
    │   └── dashboard/          # Dashboard routes & layout
    │       ├── page.tsx        # Dashboard entry point
    │       ├── layout.tsx      # Dashboard layout
    │       └── _components/    # Dashboard UI components
    ├── (external)/             # Public-facing routes
    │   └── page.tsx           # Landing/marketing pages
    ├── globals.css            # Global styles
    └── layout.tsx             # Root layout
├── components/                # Top-level UI primitives and layout elements
├── config/                   # Project configuration files and settings
├── hooks/                    # Reusable custom React hooks
├── lib/                      # Shared libraries and utility functions
├── navigation/               # Navigation-related config (sidebar items)
└── middleware.ts             # Middleware for auth, redirects, etc.
```

## Implementation Guidelines

### Server vs Client Components

- Default to Server Components unless client-side interactivity is needed
- Use `"use client"` directive for components with:
  - State management
  - Event handlers
  - Browser-only APIs
  - Interactive UI elements

### Shared Logic Placement

- Route-specific logic (schemas, types): Colocate with the route
- Cross-route shared logic: Place in top-level `lib/` folder
- Global utilities: Keep in `hooks/`, `lib/`, or `constants/` directories
- Navigation configuration: Use dedicated `navigation/` folder

### Layout Strategy

- Nested layouts for route groups enable shared UI elements
- Each route group can have its own layout (sidebar, header, etc.)
- Layouts are automatically shared by child routes

## When to Use This Pattern

### Ideal Use Cases

- Medium to large-scale applications with dozens of routes
- Teams working in parallel on different features
- Projects requiring clear boundaries between server and client components
- Applications prioritizing modularity and maintainability

### Benefits Over Traditional Patterns

- Avoids bloated global `components/` directories
- Reduces cognitive overhead and context switching
- Improves developer experience in code editors
- Supports better modularity and faster onboarding
- Enables improved discoverability of related logic

### Migration from Traditional Patterns

- Move route-specific components from global folders to colocated `_components/`
- Keep truly shared components in top-level `components/` directory
- Gradually adopt colocation for new features
- Maintain backward compatibility during transition

## Best Practices

1. **Start with colocation**: Place new components close to where they're used
2. **Promote when shared**: Move components to higher levels only when reused
3. **Use TypeScript**: Leverage type safety throughout the colocated structure
4. **Consistent naming**: Follow `_components/` convention for private folders
5. **Documentation**: Keep README files in complex route segments
6. **Testing**: Colocate tests with components using `__tests__/` or `.test.tsx` files

## Framework Compatibility

This pattern works well with:

- Next.js App Router (primary target)
- Remix
- Vite with React Router
- Nuxt.js (Vue ecosystem)
- Any framework supporting file-based or modular routing

When helping users implement this pattern, always consider their specific framework and adjust recommendations accordingly.

## Code Examples

### Route-Specific Component Structure

```typescript
// auth/login/_components/login-form.tsx
"use client";

import { useState } from "react";
import { Button } from "@/components/ui/button";

export function LoginForm() {
  const [email, setEmail] = useState("");
  // Component logic here
  return (
    <form>
      {/* Form implementation */}
    </form>
  );
}
```

### Shared Component Structure

```typescript
// auth/_components/github-signin.tsx
import { Button } from "@/components/ui/button";
import { Github } from "lucide-react";

export function GitHubSignIn() {
  return (
    <Button variant="outline">
      <Github className="mr-2 h-4 w-4" />
      Continue with GitHub
    </Button>
  );
}
```

### Route Layout Example

```typescript
// auth/layout.tsx
export default function AuthLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="max-w-md w-full space-y-8">
        {children}
      </div>
    </div>
  );
}
```

This colocation-first approach ensures scalable, maintainable, and well-organized Next.js applications.

## State Management in Colocation-First Architecture

### Global State Management Libraries

For state management libraries like Redux, Zustand, or Context API, follow these placement guidelines:

#### 1. Store Configuration and Setup

Place global store configuration in dedicated folders:

```
src/
├── lib/
│   └── store/                 # Global state management
│       ├── index.ts          # Store configuration and exports
│       ├── store.ts          # Main store setup (Redux/Zustand)
│       ├── middleware/       # Custom middleware
│       └── types.ts          # Store-related types
├── providers/                # React context providers
│   ├── store-provider.tsx    # Store provider wrapper
│   └── theme-provider.tsx    # Other global providers
└── hooks/
    ├── use-store.ts          # Global store hooks
    └── use-auth.ts           # Feature-specific hooks
```

#### 2. Feature-Based State Organization

##### Redux Toolkit (RTK Query) Structure

```
src/
├── lib/
│   └── store/
│       ├── index.ts          # Store configuration
│       ├── slices/           # Feature slices
│       │   ├── auth-slice.ts
│       │   ├── user-slice.ts
│       │   └── ui-slice.ts
│       └── api/              # RTK Query APIs
│           ├── auth-api.ts
│           ├── user-api.ts
│           └── base-api.ts
└── app/
    ├── (main)/
    │   └── dashboard/
    │       ├── _hooks/        # Route-specific hooks
    │       │   └── use-dashboard-data.ts
    │       └── _components/
```

##### Zustand Structure

```
src/
├── lib/
│   └── stores/               # Individual Zustand stores
│       ├── auth-store.ts
│       ├── user-store.ts
│       ├── ui-store.ts
│       └── index.ts          # Store exports
└── hooks/
    ├── use-auth-store.ts     # Store-specific hooks
    └── use-user-store.ts
```

##### React Context Structure

```
src/
├── contexts/                 # React contexts
│   ├── auth-context.tsx
│   ├── theme-context.tsx
│   └── user-context.tsx
├── providers/                # Provider components
│   ├── auth-provider.tsx
│   └── app-providers.tsx     # Combined providers
└── hooks/
    ├── use-auth-context.ts
    └── use-theme-context.ts
```

### Best Practices for State Management Placement

#### 1. Global vs Route-Specific State

- **Global state**: Authentication, user preferences, theme - place in `lib/store/` or `lib/stores/`
- **Route-specific state**: Form data, local UI state - keep colocated with components
- **Shared route state**: State used across multiple routes in a group - place in route group's `_hooks/` or `_stores/`

#### 2. Redux Toolkit Best Practices

```typescript
// lib/store/index.ts
import { configureStore } from "@reduxjs/toolkit";
import { authSlice } from "./slices/auth-slice";
import { userSlice } from "./slices/user-slice";
import { baseApi } from "./api/base-api";

export const store = configureStore({
  reducer: {
    auth: authSlice.reducer,
    user: userSlice.reducer,
    api: baseApi.reducer,
  },
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(baseApi.middleware),
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
```

```typescript
// lib/store/slices/auth-slice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";

interface AuthState {
  user: User | null;
  isAuthenticated: boolean;
  loading: boolean;
}

const initialState: AuthState = {
  user: null,
  isAuthenticated: false,
  loading: false,
};

export const authSlice = createSlice({
  name: "auth",
  initialState,
  reducers: {
    setUser: (state, action: PayloadAction<User>) => {
      state.user = action.payload;
      state.isAuthenticated = true;
    },
    clearUser: (state) => {
      state.user = null;
      state.isAuthenticated = false;
    },
  },
});

export const { setUser, clearUser } = authSlice.actions;
```

#### 3. Zustand Best Practices

```typescript
// lib/stores/auth-store.ts
import { create } from "zustand";
import { persist } from "zustand/middleware";

interface AuthState {
  user: User | null;
  isAuthenticated: boolean;
  login: (user: User) => void;
  logout: () => void;
}

export const useAuthStore = create<AuthState>()(
  persist(
    (set) => ({
      user: null,
      isAuthenticated: false,
      login: (user) => set({ user, isAuthenticated: true }),
      logout: () => set({ user: null, isAuthenticated: false }),
    }),
    {
      name: "auth-storage",
    },
  ),
);
```

#### 4. Route-Specific State Management

For state specific to a route or route group, create colocated stores:

```
src/app/(main)/dashboard/
├── _stores/                  # Route-specific stores
│   ├── dashboard-store.ts
│   └── filters-store.ts
├── _hooks/                   # Route-specific hooks
│   ├── use-dashboard.ts
│   └── use-filters.ts
└── _components/
    └── dashboard-filters.tsx
```

```typescript
// app/(main)/dashboard/_stores/dashboard-store.ts
import { create } from "zustand";

interface DashboardState {
  filters: FilterState;
  selectedItems: string[];
  setFilters: (filters: FilterState) => void;
  toggleItem: (id: string) => void;
}

export const useDashboardStore = create<DashboardState>((set) => ({
  filters: {},
  selectedItems: [],
  setFilters: (filters) => set({ filters }),
  toggleItem: (id) =>
    set((state) => ({
      selectedItems: state.selectedItems.includes(id)
        ? state.selectedItems.filter((item) => item !== id)
        : [...state.selectedItems, id],
    })),
}));
```

### Provider Setup in Root Layout

```typescript
// app/layout.tsx
import { StoreProvider } from '@/providers/store-provider';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <StoreProvider>
          {children}
        </StoreProvider>
      </body>
    </html>
  );
}
```

```typescript
// providers/store-provider.tsx
'use client';

import { Provider } from 'react-redux';
import { store } from '@/lib/store';

export function StoreProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  return <Provider store={store}>{children}</Provider>;
}
```

### State Management Library Recommendations

1. **Redux Toolkit + RTK Query**: Best for complex apps with heavy data fetching
2. **Zustand**: Lightweight, great for most applications, excellent TypeScript support
3. **Jotai**: Atomic state management, perfect for component-level state sharing
4. **React Context + useReducer**: Built-in solution for simple to medium complexity
5. **SWR/TanStack Query**: Excellent for server state management

Choose based on:

- **Application complexity**: Simple apps can use Context, complex apps benefit from Redux
- **Team size**: Larger teams often prefer Redux for consistency
- **Performance needs**: Zustand and Jotai offer better performance for frequent updates
- **Learning curve**: Context is familiar, Zustand is easier to learn than Redux

## Implementation Guidelines

### Server vs Client Components

- Default to Server Components unless client-side interactivity is needed
- Use `"use client"` directive for components with:
  - State management
  - Event handlers
  - Browser-only APIs
  - Interactive UI elements

### Shared Logic Placement

- Route-specific logic (schemas, types): Colocate with the route
- Cross-route shared logic: Place in top-level `lib/` folder
- Global utilities: Keep in `hooks/`, `lib/`, or `constants/` directories
- Navigation configuration: Use dedicated `navigation/` folder

### Layout Strategy

- Nested layouts for route groups enable shared UI elements
- Each route group can have its own layout (sidebar, header, etc.)
- Layouts are automatically shared by child routes

## When to Use This Pattern

### Ideal Use Cases

- Medium to large-scale applications with dozens of routes
- Teams working in parallel on different features
- Projects requiring clear boundaries between server and client components
- Applications prioritizing modularity and maintainability

### Benefits Over Traditional Patterns

- Avoids bloated global `components/` directories
- Reduces cognitive overhead and context switching
- Improves developer experience in code editors
- Supports better modularity and faster onboarding
- Enables improved discoverability of related logic

### Migration from Traditional Patterns

- Move route-specific components from global folders to colocated `_components/`
- Keep truly shared components in top-level `components/` directory
- Gradually adopt colocation for new features
- Maintain backward compatibility during transition

## Best Practices

1. **Start with colocation**: Place new components close to where they're used
2. **Promote when shared**: Move components to higher levels only when reused
3. **Use TypeScript**: Leverage type safety throughout the colocated structure
4. **Consistent naming**: Follow `_components/` convention for private folders
5. **Documentation**: Keep README files in complex route segments
6. **Testing**: Colocate tests with components using `__tests__/` or `.test.tsx` files

## Framework Compatibility

This pattern works well with:

- Next.js App Router (primary target)
- Remix
- Vite with React Router
- Nuxt.js (Vue ecosystem)
- Any framework supporting file-based or modular routing

When helping users implement this pattern, always consider their specific framework and adjust recommendations accordingly.

## Code Examples

### Route-Specific Component Structure

```typescript
// auth/login/_components/login-form.tsx
"use client";

import { useState } from "react";
import { Button } from "@/components/ui/button";

export function LoginForm() {
  const [email, setEmail] = useState("");
  // Component logic here
  return (
    <form>
      {/* Form implementation */}
    </form>
  );
}
```

### Shared Component Structure

```typescript
// auth/_components/github-signin.tsx
import { Button } from "@/components/ui/button";
import { Github } from "lucide-react";

export function GitHubSignIn() {
  return (
    <Button variant="outline">
      <Github className="mr-2 h-4 w-4" />
      Continue with GitHub
    </Button>
  );
}
```

### Route Layout Example

```typescript
// auth/layout.tsx
export default function AuthLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="max-w-md w-full space-y-8">
        {children}
      </div>
    </div>
  );
}
```

This colocation-first approach ensures scalable, maintainable, and well-organized Next.js applications.

## State Management in Colocation-First Architecture

### Global State Management Libraries

For state management libraries like Redux, Zustand, or Context API, follow these placement guidelines:

#### 1. Store Configuration and Setup

Place global store configuration in dedicated folders:

```
src/
├── lib/
│   └── store/                 # Global state management
│       ├── index.ts          # Store configuration and exports
│       ├── store.ts          # Main store setup (Redux/Zustand)
│       ├── middleware/       # Custom middleware
│       └── types.ts          # Store-related types
├── providers/                # React context providers
│   ├── store-provider.tsx    # Store provider wrapper
│   └── theme-provider.tsx    # Other global providers
└── hooks/
    ├── use-store.ts          # Global store hooks
    └── use-auth.ts           # Feature-specific hooks
```

#### 2. Feature-Based State Organization

##### Redux Toolkit (RTK Query) Structure

```
src/
├── lib/
│   └── store/
│       ├── index.ts          # Store configuration
│       ├── slices/           # Feature slices
│       │   ├── auth-slice.ts
│       │   ├── user-slice.ts
│       │   └── ui-slice.ts
│       └── api/              # RTK Query APIs
│           ├── auth-api.ts
│           ├── user-api.ts
│           └── base-api.ts
└── app/
    ├── (main)/
    │   └── dashboard/
    │       ├── _hooks/        # Route-specific hooks
    │       │   └── use-dashboard-data.ts
    │       └── _components/
```

##### Zustand Structure

```
src/
├── lib/
│   └── stores/               # Individual Zustand stores
│       ├── auth-store.ts
│       ├── user-store.ts
│       ├── ui-store.ts
│       └── index.ts          # Store exports
└── hooks/
    ├── use-auth-store.ts     # Store-specific hooks
    └── use-user-store.ts
```

##### React Context Structure

```
src/
├── contexts/                 # React contexts
│   ├── auth-context.tsx
│   ├── theme-context.tsx
│   └── user-context.tsx
├── providers/                # Provider components
│   ├── auth-provider.tsx
│   └── app-providers.tsx     # Combined providers
└── hooks/
    ├── use-auth-context.ts
    └── use-theme-context.ts
```

### Best Practices for State Management Placement

#### 1. Global vs Route-Specific State

- **Global state**: Authentication, user preferences, theme - place in `lib/store/` or `lib/stores/`
- **Route-specific state**: Form data, local UI state - keep colocated with components
- **Shared route state**: State used across multiple routes in a group - place in route group's `_hooks/` or `_stores/`

#### 2. Redux Toolkit Best Practices

```typescript
// lib/store/index.ts
import { configureStore } from "@reduxjs/toolkit";
import { authSlice } from "./slices/auth-slice";
import { userSlice } from "./slices/user-slice";
import { baseApi } from "./api/base-api";

export const store = configureStore({
  reducer: {
    auth: authSlice.reducer,
    user: userSlice.reducer,
    api: baseApi.reducer,
  },
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(baseApi.middleware),
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
```

```typescript
// lib/store/slices/auth-slice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";

interface AuthState {
  user: User | null;
  isAuthenticated: boolean;
  loading: boolean;
}

const initialState: AuthState = {
  user: null,
  isAuthenticated: false,
  loading: false,
};

export const authSlice = createSlice({
  name: "auth",
  initialState,
  reducers: {
    setUser: (state, action: PayloadAction<User>) => {
      state.user = action.payload;
      state.isAuthenticated = true;
    },
    clearUser: (state) => {
      state.user = null;
      state.isAuthenticated = false;
    },
  },
});

export const { setUser, clearUser } = authSlice.actions;
```

#### 3. Zustand Best Practices

```typescript
// lib/stores/auth-store.ts
import { create } from "zustand";
import { persist } from "zustand/middleware";

interface AuthState {
  user: User | null;
  isAuthenticated: boolean;
  login: (user: User) => void;
  logout: () => void;
}

export const useAuthStore = create<AuthState>()(
  persist(
    (set) => ({
      user: null,
      isAuthenticated: false,
      login: (user) => set({ user, isAuthenticated: true }),
      logout: () => set({ user: null, isAuthenticated: false }),
    }),
    {
      name: "auth-storage",
    },
  ),
);
```

#### 4. Route-Specific State Management

For state specific to a route or route group, create colocated stores:

```
src/app/(main)/dashboard/
├── _stores/                  # Route-specific stores
│   ├── dashboard-store.ts
│   └── filters-store.ts
├── _hooks/                   # Route-specific hooks
│   ├── use-dashboard.ts
│   └── use-filters.ts
└── _components/
    └── dashboard-filters.tsx
```

```typescript
// app/(main)/dashboard/_stores/dashboard-store.ts
import { create } from "zustand";

interface DashboardState {
  filters: FilterState;
  selectedItems: string[];
  setFilters: (filters: FilterState) => void;
  toggleItem: (id: string) => void;
}

export const useDashboardStore = create<DashboardState>((set) => ({
  filters: {},
  selectedItems: [],
  setFilters: (filters) => set({ filters }),
  toggleItem: (id) =>
    set((state) => ({
      selectedItems: state.selectedItems.includes(id)
        ? state.selectedItems.filter((item) => item !== id)
        : [...state.selectedItems, id],
    })),
}));
```

### Provider Setup in Root Layout

```typescript
// app/layout.tsx
import { StoreProvider } from '@/providers/store-provider';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <StoreProvider>
          {children}
        </StoreProvider>
      </body>
    </html>
  );
}
```

```typescript
// providers/store-provider.tsx
'use client';

import { Provider } from 'react-redux';
import { store } from '@/lib/store';

export function StoreProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  return <Provider store={store}>{children}</Provider>;
}
```

### State Management Library Recommendations

1. **Redux Toolkit + RTK Query**: Best for complex apps with heavy data fetching
2. **Zustand**: Lightweight, great for most applications, excellent TypeScript support
3. **Jotai**: Atomic state management, perfect for component-level state sharing
4. **React Context + useReducer**: Built-in solution for simple to medium complexity
5. **SWR/TanStack Query**: Excellent for server state management

Choose based on:

- **Application complexity**: Simple apps can use Context, complex apps benefit from Redux
- **Team size**: Larger teams often prefer Redux for consistency
- **Performance needs**: Zustand and Jotai offer better performance for frequent updates
- **Learning curve**: Context is familiar, Zustand is easier to learn than Redux
