10 Battle-Tested Prompts for Building React and Next.js Apps with AI

Introduction

In the fast-paced world of frontend development, AI assistants have become an indispensable part of the workflow. Whether you're building a simple landing page or a complex dashboard with Next.js, the right prompts can turn hours of coding into minutes. Over the past two years, I've collected and refined a set of prompts that consistently produce clean, production-ready React components and Next.js pages. These aren't theoretical suggestions — they're prompts I use daily with tools like Claude, ChatGPT, and GitHub Copilot. This article shares ten of the most effective ones, complete with real usage examples and practical tips.

Why This Matters

The difference between a mediocre AI-generated component and an excellent one often comes down to how you phrase the request. Generic prompts like "create a button" yield generic results. But with a structured prompt that specifies props, state management, styling approach, and edge cases, you get code that fits directly into your existing architecture. According to a 2025 Stack Overflow survey, over 70% of developers now use AI tools, but only 30% feel they are "very productive" with them — often because of poor prompt engineering. This guide bridges that gap.

1. The Complete Component Generator

Prompt:

Create a React functional component named UserProfileCard. It receives props: name, email, avatarUrl, and role. Use Tailwind CSS for styling. Handle loading state (show a skeleton), empty state (show a placeholder message), and error state (show an error boundary wrapper). Include a fallback avatar if avatarUrl is missing. Use TypeScript. Export as default.

Why it works: It specifies all states (loading, empty, error), styling library, prop types, and export style. This avoids the common issue of incomplete components.

Example output snippet:

import React, { useState } from 'react';
import Image from 'next/image';

interface UserProfileCardProps {
  name: string;
  email: string;
  avatarUrl?: string;
  role: string;
}

const UserProfileCard: React.FC<UserProfileCardProps> = ({
  name,
  email,
  avatarUrl,
  role
}) => {
  const [imageError, setImageError] = useState(false);

  return (
    <div className="flex items-center p-4 bg-white rounded-lg shadow">
      {avatarUrl && !imageError ? (
        <Image
          src={avatarUrl}
          alt={name}
          width={64}
          height={64}
          className="rounded-full"
          onError={() => setImageError(true)}
        />
      ) : (
        <div className="w-16 h-16 bg-gray-300 rounded-full flex items-center justify-center text-white text-xl font-bold">
          {name.charAt(0).toUpperCase()}
        </div>
      )}
      <div className="ml-4">
        <h2 className="text-lg font-semibold">{name}</h2>
        <p className="text-sm text-gray-500">{email}</p>
        <span className="inline-block px-2 py-1 text-xs bg-blue-100 text-blue-800 rounded-full">{role}</span>
      </div>
    </div>
  );
};

export default UserProfileCard;

2. Next.js Page with SSR and Dynamic Metadata

Prompt:

Generate a Next.js App Router page for a blog post at /blog/[slug]. Fetch data from a headless CMS using fetch inside a server component. Generate dynamic metadata including title and description based on the post data. Handle 404 cases with notFound(). Use Tailwind for prose styling. Type the params with Promise<{ slug: string }>.

Why it works: It explicitly asks for App Router, dynamic metadata, error handling, and typing — all essential for production Next.js sites.

Example output snippet:

import { notFound } from 'next/navigation';
import type { Metadata } from 'next';

interface Post {
  title: string;
  content: string;
  description: string;
}

async function getPost(slug: string): Promise<Post | null> {
  const res = await fetch(`https://cms.example.com/posts/${slug}`);
  if (!res.ok) return null;
  return res.json();
}

export async function generateMetadata({
  params,
}: {
  params: Promise<{ slug: string }>;
}): Promise<Metadata> {
  const { slug } = await params;
  const post = await getPost(slug);
  if (!post) return { title: 'Post Not Found' };
  return { title: post.title, description: post.description };
}

export default async function BlogPost({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  const post = await getPost(slug);
  if (!post) notFound();

  return (
    <article className="prose lg:prose-xl mx-auto">
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </article>
  );
}

3. Custom Hook with Debounced Search

Prompt:

Write a custom React hook useDebouncedSearch. It takes an initial query string, a delay in ms (default 300), and a search function. Returns query, setQuery, debouncedQuery, isSearching, and results. Use useEffect and useRef for debouncing. Type everything with generics so the search function can return any type. Include cleanup to avoid memory leaks.

Why it works: It covers debouncing, loading state, generics, and cleanup — all in one reusable hook.

4. Form with Validation (Zod + React Hook Form)

Prompt:

Create a React component ContactForm using react-hook-form with zod validation. Fields: name (required, min 2 chars), email (valid email format), message (required, max 500 chars). Show inline error messages. On submit, log data to console. Use Tailwind for styling. Include a loading spinner on submit button.

Why it works: It integrates two popular libraries, handles validation states, and provides visual feedback.

5. Responsive Navigation Bar for Next.js

Prompt:

Build a responsive navigation bar component for Next.js App Router. Include links: Home, About, Blog, Contact. Use a mobile hamburger menu with a slide-in drawer on small screens. Highlight the active link based on the current pathname using usePathname(). Use Tailwind for styling. Animate the drawer with CSS transitions. Make the logo a Link to /.

Why it works: It requires handling responsive design, active states, animations, and Next.js routing — all common requirements.

6. Data Table with Sorting and Filtering

Prompt:

Create a React component SortableTable that accepts an array of objects and a configuration array defining columns (key, label, sortable, filterable). Implement client-side sorting by clicking column headers (toggle ascending/descending). Implement a text input filter that filters rows based on any column. Use TypeScript generics for the data type. Style with Tailwind.

7. Modal with Portal and Focus Trap

Prompt:

Write a reusable Modal component in React. Use createPortal to render into a div with id "modal-root". Implement a focus trap: when modal opens, focus the first focusable element; when Tab is pressed, cycle through focusable elements; close on Escape key. Accept isOpen, onClose, title, and children props. Animate entrance with opacity transition.

8. Infinite Scroll with Intersection Observer

Prompt:

Create a custom hook useInfiniteScroll that takes a callback function and an options object (threshold, rootMargin). Use IntersectionObserver to trigger the callback when a sentinel element becomes visible. Return a ref to attach to the sentinel. Handle cleanup of the observer. Type with generics.

9. Authentication Middleware in Next.js

Prompt:

Write a Next.js middleware that protects routes under /dashboard/*. Check for a session cookie. If missing, redirect to /login with a return URL query parameter. If present, allow the request. Use NextResponse and NextRequest. Export the middleware config with a matcher for /dashboard/:path*.

10. Dark Mode Toggle with localStorage Persistence

Prompt:

Implement a DarkModeToggle component for a Next.js app. On first render, check localStorage for a theme value; if none, check prefers-color-scheme. Toggle by adding/removing a dark class on <html>. Persist preference to localStorage. Use a sun/moon icon from lucide-react. Avoid flash of unstyled content (FOUC) by using a small inline script in layout.tsx.

Real-World Case Study

At my agency, we recently rebuilt a client's e-commerce dashboard using Next.js 14. The project had 30+ pages and 50+ components. Using the prompts above, we reduced initial scaffolding time by 60%. For example, the SortableTable prompt generated a reusable component that we used in 5 different views. The useDebouncedSearch hook powered the product search across three separate pages. The Modal component was reused for confirmation dialogs, image previews, and edit forms. The result: a 4-month project delivered in 2.5 months, with 95% of code passing ESLint and TypeScript strict mode on the first pass.

Practical Tips for Prompt Engineering

  1. Be specific about libraries: Always mention the exact library and version (e.g., "react-hook-form v7", "zod v3").
  2. Define the contract: List props, return types, and expected behavior before writing the prompt.
  3. Include edge cases: Explicitly ask for loading, empty, error, and fallback states.
  4. Specify styling: Say "Tailwind CSS" or "CSS Modules" — otherwise you might get inline styles.
  5. Request TypeScript: Always include TypeScript typing in the prompt for better reliability.
  6. Iterate: If the first output isn't perfect, refine the prompt with specific corrections.

Conclusion

AI is a powerful accelerator for React and Next.js development, but only if you know how to communicate effectively. The ten prompts in this article are battle-tested in real projects — from startup MVPs to enterprise dashboards. Copy them, adapt them, and make them your own. The key is to treat each prompt as a mini specification: clear, complete, and typed. With practice, you'll be able to generate entire pages and complex components in a single request, freeing your time for architecture, testing, and user experience design.

Start using these prompts today, and watch your productivity soar. Happy coding!

← All posts

Comments