Nextjs Component Generator

Generate optimized React components for Next.js with TypeScript and best practices

Commandnextjs vercelMIT1 source files

Before you use this component

This is a third-party source bundle, not an installation into your account. UI Discovery has checked the available redistribution license evidence; runtime behavior has not been tested. Review all files, use a disposable project first, and do not enable scripts or hooks until you understand their permissions.

Some integrations require separately installed software, API keys or paid services. Credentials and subscriptions are not included. These are Claude Code resources; other clients may require adaptation.

Extract the ZIP into a temporary folder, inspect its entry file and supporting resources, then follow the original instructions. Do not overwrite an existing project configuration blindly. Keep the bundled license and attribution notices.

Source publisher
Claude Code Templates
Creator supplied by source
Not listed in source
Pinned source version
a344359459263d73d8948651c789244093c02e4e
License evidence
LICENSE

Source preview

cli-tool/components/commands/nextjs-vercel/nextjs-component-generator.md

---
allowed-tools: Read, Write, Edit
argument-hint: [component-name] [--client] [--server] [--page] [--layout]
description: Generate optimized React components for Next.js with TypeScript and best practices
---

## Next.js Component Generator

**Component Name**: $ARGUMENTS

## Project Context Analysis

### Framework Detection
- Next.js config: @next.config.js
- TypeScript config: @tsconfig.json (if exists)
- Tailwind config: @tailwind.config.js (if exists)
- Package.json: @package.json

### Existing Component Patterns
- Components directory: @components/
- App directory: @app/ (if App Router)
- Pages directory: @pages/ (if Pages Router)
- Styles directory: @styles/

## Component Generation Requirements

### 1. Component Type Detection
Based on arguments and context, determine component type:
- **Client Component**: Interactive UI with state/events (`--client` or default for interactive components)
- **Server Component**: Static rendering, data fetching (`--server` or default for Next.js 13+)
- **Page Component**: Route-level component (`--page`)
- **Layout Component**: Shared layout wrapper (`--layout`)

### 2. File Structure Creation
Generate comprehensive component structure:
```
components/[ComponentName]/
├── index.ts                    # Barrel export
├── [ComponentName].tsx         # Main component
├── [ComponentName].module.css  # Component styles
├── [ComponentName].test.tsx    # Unit tests
├── [ComponentName].stories.tsx # Storybook story (if detected)
└── types.ts                   # TypeScript types
```

### 3. Component Templates

#### Server Component Template
```typescript
import { FC } from 'react';
import styles from './ComponentName.module.css';

interface ComponentNameProps {
  /**
   * Component description
   */
  children?: React.ReactNode;
  /**
   * Additional CSS classes
   */
  className?: string;
}

/**
 * ComponentName - Server Component
 * 
 * @description Brief description of component purpose
 * @example
 * <ComponentName>Content</ComponentName>
 */
export const ComponentName: FC<ComponentNameProps> = ({
  children,
  className = '',
  ...props
}) => {
  return (
    <div className={`${styles.container} ${className}`} {...props}>
      {children}
    </div>
  );
};

export default ComponentName;
```

#### Client Component Template
```typescript
'use client';

import { FC, useState, useEffect } from 'react';
import styles from './ComponentName.module.css';

interface ComponentNameProps {
  /**
   * Component description
   */
  children?: React.ReactNode;
  /**
   * Click event handler
   */
  onClick?: () => void;
  /**
   * Additional CSS classes
   */
  className?: string;
}

/**
 * ComponentName - Client Component
 * 
 * @description Interactive component with client-side functionality
 * @example
 * <ComponentName onClick={() => console.log('clicked')}>
 *   Content
 * </ComponentName>
 */
export const ComponentName: FC<ComponentNameProps> = ({
  children,
  onClick,
  className = '',
  ...props
}) => {
  const [isActive, setIsActive] = useState(false);

  const handleClick = () => {
    setIsActive(!isActive);
    onClick?.();
  };

  return (
    <button
      className={`${styles.button} ${isActive ? styles.active : ''} ${className}`}
      onClick={handleClick}
      {...props}
    >
      {children}
    </button>
  );
};

export default ComponentName;
```

#### Page Component Template
```typescript
import { Metadata } from 'next';
import ComponentName from '@/components/ComponentName';

export const metadata: Metadata = {
  title: 'Page Title',
  description: 'Page description',
};

interface PageProps {
  params: { id: string };
  searchParams: { [key: string]: string | string[] | undefined };
}

export default function Page({ params, searchParams }: PageProps) {
  return (
    <main>
      <h1>Page Title</h1>
      <ComponentName />
    </main>
  );
}
```

#### Layout Component Template
```typescript
import { FC } from 'react';
import styles from './Layout.module.css';

interface LayoutProps {
  children: React.ReactNode;
  /**
   * Page title
   */
  title?: string;
}

/**
 * Layout - Shared layout component
 * 
 * @description Provides consistent layout structure across pages
 */
export const Layout: FC<LayoutProps> = ({
  children,
  title,
}) => {
  return (
    <div className={styles.layout}>
      <header className={styles.header}>
        {title && <h1 className={styles.title}>{title}</h1>}
      </header>
      
      <main className={styles.main}>
        {children}
      </main>
      
      <footer className={styles.footer}>
        <p>&copy; 2024 Your App</p>
      </footer>
    </div>
  );
};

export default Layout;
```

### 4. CSS Module Templates

#### Basic Component Styles
```css
/* ComponentName.module.css */
.container {
  display: flex;
  flex-direction: column;
  padding: 1rem;
  border-radius: 8px;
  border: 1px solid #e2e8f0;
  background-color: #ffffff;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 1rem;
  border-radius: 6px;
  border: 1px solid transparent;
  background-color: #3b82f6;
  color: white;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
}

.button:hover {
  background-color: #2563eb;
}

.button:focus {
  outline: 2px solid #3b82f6;
  outline-offset: 2px;
}

.button.active {
  background-color: #1d4ed8;
}

/* Responsive design */
@media (max-width: 768px) {
  .container {
    padding: 0.75rem;
  }
  
  .button {
    padding: 0.75rem 1rem;
  }
}
```

#### Layout Styles
```css
/* Layout.module.css */
.layout {
  min-height: 100vh;
  display: grid;
  grid-template-rows: auto 1fr auto;
}

.header {
  padding: 1rem 2rem;
  background-color: #f8fafc;
  border-bottom: 1px solid #e2e8f0;
}

.title {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 600;
  color: #1e293b;
}

.main {
  padding: 2rem;
  max-width: 1200px;
  margin: 0 auto;
  width: 100%;
}

.footer {
  padding: 1rem 2rem;
  background-color: #f1f5f9;
  border-top: 1px solid #e2e8f0;
  text-align: center;
  color: #64748b;
}
```

### 5. TypeScript Types
```typescript
// types.ts
export interface BaseComponentProps {
  children?: React.ReactNode;
  className?: string;
  'data-testid'?: string;
}

export interface ButtonProps extends BaseComponentProps {
  variant?: 'primary' | 'secondary' | 'outline';
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
  loading?: boolean;
  onClick?: () => void;
}

export interface LayoutProps extends BaseComponentProps {
  title?: string;
  sidebar?: React.ReactNode;
  breadcrumbs?: BreadcrumbItem[];
}

export interface BreadcrumbItem {
  label: string;
  href?: string;
  current?: boolean;
}
```

### 6. Unit Tests
```typescript
// ComponentName.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import ComponentName from './ComponentName';

describe('ComponentName', () => {
  it('renders children correctly', () => {
    render(<ComponentName>Test Content</ComponentName>);
    expect(screen.getByText('Test Content')).toBeInTheDocument();
  });

  it('applies custom className', () => {
    render(<ComponentName className="custom-class">Test</ComponentName>);
    const element = screen.getByText('Test');
    expect(element).toHaveClass('custom-class');
  });

  it('handles click events', () => {
    const handleClick = jest.fn();
    render(<ComponentName onClick={handleClick}>Click me</ComponentName>);
    
    const button = screen.getByText('Click me');
    fireEvent.click(button);
    
    expect(handleClick).toHaveBeenCalledTimes(1);
  });

  it('toggles active state on click', () => {
    render(<ComponentName>Toggle</ComponentName>);
    const button = screen.getByText('Toggle');
    
    expect(button).not.toHaveClass('active');
    
    fireEvent.click(button);
    expect(button).toHaveClass('active');
    
    fireEvent.click(button);
    expect(button).not.toHaveClass('active');
  });

  it('is accessible', () => {
    render(<ComponentName>Accessible Button</ComponentName>);
    const button = screen.getByRole('button');
    
    expect(button).toBeInTheDocument();
    expect(button).toHaveAccessibleName('Accessible Button');
  });
});
```

### 7. Storybook Stories (if detected)
```typescript
// ComponentName.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import ComponentName from './ComponentName';

const meta: Meta<typeof ComponentName> = {
  title: 'Components/ComponentName',
  component: ComponentName,
  parameters: {
    layout: 'centered',
    docs: {
      description: {
        component: 'A reusable component built for Next.js applications.',
      },
    },
  },
  tags: ['autodocs'],
  argTypes: {
    onClick: { action: 'clicked' },
    className: { control: 'text' },
  },
};

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
  args: {
    children: 'Default Component',
  },
};

export const WithCustomClass: Story = {
  args: {
    children: 'Custom Styled',
    className: 'custom-style',
  },
};

export const Interactive: Story = {
  args: {
    children: 'Click me',
    onClick: () => alert('Component clicked!'),
  },
};
```

### 8. Barrel Export
```typescript
// index.ts
export { default } from './ComponentName';
export type { ComponentNameProps } from './ComponentName';
```

## Framework-Specific Optimizations

### Tailwind CSS Integration (if detected)
Replace CSS modules with Tailwind classes:
```typescript
export const ComponentName: FC<ComponentNameProps> = ({
  children,
  className = '',
}) => {
  return (
    <div className={`flex flex-col p-4 rounded-lg border border-slate-200 bg-white ${className}`}>
      {children}
    </div>
  );
};
```

### Next.js App Router Optimizations
- **Server Components**: Default for non-interactive components
- **Client Components**: Explicit 'use client' directive
- **Metadata**: Include metadata for page components
- **Loading States**: Implement loading.tsx for async components

### Accessibility Features
- **ARIA Labels**: Proper labeling for screen readers
- **Keyboard Navigation**: Tab order and keyboard shortcuts
- **Focus Management**: Visible focus indicators
- **Semantic HTML**: Proper semantic elements

## Component Generation Process

1. **Analysis**: Analyze existing project structure and patterns
2. **Template Selection**: Choose appropriate template based on component type
3. **Customization**: Adapt template to project conventions
4. **File Creation**: Generate all component files
5. **Integration**: Update index files and exports
6. **Validation**: Verify component compiles and tests pass

## Quality Checklist

- [ ] Component follows project naming conventions
- [ ] TypeScript types are properly defined
- [ ] CSS follows established patterns (modules or Tailwind)
- [ ] Unit tests cover key functionality
- [ ] Component is accessible (ARIA, keyboard navigation)
- [ ] Documentation includes usage examples
- [ ] Storybook story created (if Storybook detected)
- [ ] Component compiles without errors
- [ ] Tests pass successfully

Provide the complete component implementation with all specified files and features.

Preview capped at 60,000 characters. Download the bundle for every original file and notice.

Read the redistribution license
MIT License

Copyright (c) 2025 Daniel (San) Ávila

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Bundle SHA-256: a6f9fd369f7b27e6ba77b5d3d836dba155f38bdf8b08d6eb38f61a39a185284a. Files are served as downloads and are never executed by this page.