Use when adding new error messages to React, or seeing "unknown error code" warnings.
npx skills add DauQuangThanh/hanoi-rainbow --skill "mockup-creation"
Install specific skill from multi-skill repository
# Description
Create interactive, production-ready UI mockups and prototypes using NuxtJS 4 (Vue) or Next.js (React), TypeScript, and TailwindCSS v4. Use when building web mockups, prototypes, landing pages, dashboards, admin panels, or interactive UI demonstrations. Trigger when users mention "create mockup", "build prototype", "interactive demo", "UI prototype", "design to code", or need rapid frontend development with modern tooling. Prefer NuxtJS for Vue-based projects; use Next.js when users mention ReactJS.
# SKILL.md
name: mockup-creation
description: Create interactive, production-ready UI mockups and prototypes using NuxtJS 4 (Vue) or Next.js (React), TypeScript, and TailwindCSS v4. Use when building web mockups, prototypes, landing pages, dashboards, admin panels, or interactive UI demonstrations. Trigger when users mention "create mockup", "build prototype", "interactive demo", "UI prototype", "design to code", or need rapid frontend development with modern tooling. Prefer NuxtJS for Vue-based projects; use Next.js when users mention ReactJS.
license: MIT
compatibility: Requires Node.js 20.x or newer
Mockup Creation
Create polished, interactive UI mockups and prototypes using NuxtJS 4 (Vue) or Next.js (React) with TypeScript and TailwindCSS v4.
Overview
Rapid creation of production-quality mockups with:
NuxtJS 4 (Vue):
- Vue 3 Composition API with TypeScript
- Vite bundler (built-in)
- Auto-imports for components and composables
- Zero-config TypeScript with auto-generated types
- File-based routing from pages/ directory
Next.js (React):
- React 19 with TypeScript v5.1.0+
- Turbopack bundler (default, faster than Webpack)
- App Router with Server/Client Components
- Built-in TypeScript with zero configuration
- File-based routing from app/ directory
Common Features:
- TailwindCSS v4 with modern tooling
- Component-driven architecture
- Server-side rendering (SSR) or static site generation (SSG)
- Interactive reactivity
- Production-ready optimizations
Quick Start
Option A: NuxtJS 4 (Vue-based)
Option A: NuxtJS 4 (Vue-based)
1. Initialize Project
# Create NuxtJS 4 project (TypeScript enabled by default)
npx nuxi@latest init my-mockup
cd my-mockup
npm install
2. Install and Configure TailwindCSS
Install TailwindCSS v4 with Vite plugin:
npm install -D tailwindcss @tailwindcss/vite
Configure nuxt.config.ts:
// https://nuxt.com/docs/4.x/api/configuration/nuxt-config
import tailwindcss from '@tailwindcss/vite'
export default defineNuxtConfig({
devtools: { enabled: true },
typescript: {
strict: true,
typeCheck: true
},
// Auto-import components and composables
components: [
{
path: '~/components',
pathPrefix: false,
},
],
// App configuration
app: {
head: {
charset: 'utf-8',
viewport: 'width=device-width, initial-scale=1',
title: 'My Mockup',
meta: [
{ name: 'description', content: 'My mockup description' }
],
}
},
// Vite configuration with TailwindCSS v4
vite: {
plugins: [
tailwindcss()
],
css: {
devSourcemap: true
}
}
})
Create CSS file and import TailwindCSS (e.g., assets/css/main.css):
@import "tailwindcss";
Import CSS in app.vue or nuxt.config.ts:
// In nuxt.config.ts, add to the config:
export default defineNuxtConfig({
css: ['~/assets/css/main.css'],
// ... rest of config
})
3. Start Development
npm run dev
# Opens http://localhost:3000
Option B: Next.js (React-based)
1. Initialize Project
# Create Next.js project (uses recommended defaults with TypeScript and TailwindCSS)
npx create-next-app@latest my-mockup --yes
cd my-mockup
Or with custom options:
npx create-next-app@latest my-mockup
# Choose: TypeScript: Yes, TailwindCSS: Yes, App Router: Yes
2. Verify TailwindCSS v4 Setup
Next.js includes TailwindCSS by default. To upgrade to v4:
npm install -D tailwindcss@next @tailwindcss/postcss@next
Update tailwind.config.ts:
import type { Config } from 'tailwindcss'
export default {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
],
} satisfies Config
Update postcss.config.mjs:
export default {
plugins: {
'@tailwindcss/postcss': {},
},
}
Update app/globals.css:
@import "tailwindcss";
3. Start Development
npm run dev
# Opens http://localhost:3000
Workflow
1. Define Structure
Identify mockup requirements:
- Layout type (single page, dashboard, multi-page)
- Sections needed (header, hero, features, footer, sidebar)
- Responsive breakpoints (mobile, tablet, desktop)
- Interactive elements (forms, modals, dropdowns)
2. Create Component Architecture
NuxtJS (Vue) auto-imports from:
my-mockup/
├── components/
│ ├── layout/ # Header, Footer, Sidebar (auto-imported)
│ ├── ui/ # Button, Card, Modal, Input (auto-imported)
│ └── sections/ # Hero, Features, Testimonials (auto-imported)
├── pages/ # File-based routing (auto-routed)
├── composables/ # Shared logic (auto-imported)
├── layouts/ # Layout templates (default.vue, dashboard.vue)
└── types/ # TypeScript interfaces
Next.js (React) structure:
my-mockup/
├── app/
│ ├── layout.tsx # Root layout (required)
│ ├── page.tsx # Home page
│ ├── dashboard/
│ │ └── page.tsx # /dashboard route
│ └── globals.css # TailwindCSS imports
├── components/
│ ├── layout/ # Header, Footer, Sidebar
│ ├── ui/ # Button, Card, Modal, Input
│ └── sections/ # Hero, Features, Testimonials
├── lib/ # Utilities and shared logic
└── types/ # TypeScript interfaces
3. Build Components
NuxtJS (Vue) Example: Type-safe Button Component (components/ui/Button.vue)
<script setup lang="ts">
// No need to import 'computed' - auto-imported by Nuxt
interface Props {
variant?: 'primary' | 'secondary' | 'outline'
size?: 'sm' | 'md' | 'lg'
}
const props = withDefaults(defineProps<Props>(), {
variant: 'primary',
size: 'md'
})
const buttonClasses = computed(() => {
const variants = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-600 text-white hover:bg-gray-700',
outline: 'border-2 border-blue-600 text-blue-600 hover:bg-blue-50'
}
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg'
}
return `font-semibold rounded-lg transition ${variants[props.variant]} ${sizes[props.size]}`
})
</script>
<template>
<button :class="buttonClasses">
<slot />
</button>
</template>
Usage in pages/index.vue:
<template>
<div>
<!-- Auto-imported as UiButton from components/ui/Button.vue -->
<UiButton variant="primary" size="lg">
Get Started
</UiButton>
</div>
</template>
Next.js (React) Example: Type-safe Button Component (components/ui/Button.tsx)
import { ButtonHTMLAttributes } from 'react'
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'outline'
size?: 'sm' | 'md' | 'lg'
children: React.ReactNode
}
export function Button({
variant = 'primary',
size = 'md',
children,
className = '',
...props
}: ButtonProps) {
const variants = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-600 text-white hover:bg-gray-700',
outline: 'border-2 border-blue-600 text-blue-600 hover:bg-blue-50'
}
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg'
}
const buttonClasses = `font-semibold rounded-lg transition ${variants[variant]} ${sizes[size]} ${className}`
return (
<button className={buttonClasses} {...props}>
{children}
</button>
)
}
Usage in app/page.tsx:
import { Button } from '@/components/ui/Button'
export default function Home() {
return (
<div>
<Button variant="primary" size="lg">
Get Started
</Button>
</div>
)
}
4. Apply Responsive Design
Use TailwindCSS breakpoints:
sm:(640px),md:(768px),lg:(1024px),xl:(1280px),2xl:(1536px)
NuxtJS (Vue) Responsive Grid Example:
<template>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Auto-imported as UiCard from components/ui/Card.vue -->
<UiCard v-for="item in items" :key="item.id" :data="item" />
</div>
</template>
<script setup lang="ts">
const items = ref([...])
</script>
Next.js (React) Responsive Grid Example:
import { Card } from '@/components/ui/Card'
export default function FeaturesSection() {
const items = [
{ id: 1, title: 'Feature 1', description: '...' },
// ...
]
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{items.map((item) => (
<Card key={item.id} data={item} />
))}
</div>
)
}
5. Add Interactivity
NuxtJS (Vue) Composable Pattern (composables/useModal.ts):
// Auto-imported by Nuxt - no need to import 'ref'
export function useModal() {
const isOpen = ref(false)
const open = () => { isOpen.value = true }
const close = () => { isOpen.value = false }
return { isOpen, open, close }
}
Usage in any Vue component:
<script setup lang="ts">
// Auto-imported - no import statement needed
const { isOpen, open, close } = useModal()
</script>
Next.js (React) Custom Hook Pattern (lib/hooks/useModal.ts):
import { useState } from 'react'
export function useModal() {
const [isOpen, setIsOpen] = useState(false)
const open = () => setIsOpen(true)
const close = () => setIsOpen(false)
return { isOpen, open, close }
}
Usage in any React component:
'use client' // Mark as Client Component for interactivity
import { useModal } from '@/lib/hooks/useModal'
export default function MyComponent() {
const { isOpen, open, close } = useModal()
return (
<div>
<button onClick={open}>Open Modal</button>
{isOpen && <Modal onClose={close} />}
</div>
)
}
6. Build for Production
NuxtJS:
npm run build # Build for production (.output/)
npm run preview # Preview production build
npm run generate # Generate static site (SSG)
Next.js:
npm run build # Build for production (.next/)
npm run start # Start production server (SSR)
# For static export (SSG), add to next.config.js:
# output: 'export'
Common Patterns
Landing Page (NuxtJS)
Create layout (layouts/default.vue):
<template>
<div class="min-h-screen flex flex-col">
<LayoutHeader />
<main class="flex-1">
<slot />
</main>
<LayoutFooter />
</div>
</template>
Create page (pages/index.vue):
<template>
<div>
<SectionsHero />
<SectionsFeatures />
</div>
</template>
Landing Page (Next.js)
Create layout (app/layout.tsx):
import { Header } from '@/components/layout/Header'
import { Footer } from '@/components/layout/Footer'
import './globals.css'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className="min-h-screen flex flex-col">
<Header />
<main className="flex-1">{children}</main>
<Footer />
</body>
</html>
)
}
Create page (app/page.tsx):
import { Hero } from '@/components/sections/Hero'
import { Features } from '@/components/sections/Features'
export default function Home() {
return (
<div>
<Hero />
<Features />
</div>
)
}
Dashboard Layout (NuxtJS)
Create dashboard layout (layouts/dashboard.vue):
<template>
<div class="flex h-screen bg-gray-100">
<LayoutSidebar class="w-64 bg-white shadow-lg" />
<div class="flex-1 flex flex-col">
<LayoutTopBar class="bg-white shadow-sm" />
<main class="flex-1 overflow-y-auto p-6">
<slot />
</main>
</div>
</div>
</template>
Use in page (pages/dashboard/index.vue):
<script setup lang="ts">
definePageMeta({
layout: 'dashboard'
})
</script>
<template>
<div>
<!-- Dashboard content -->
</div>
</template>
Dashboard Layout (Next.js)
Create dashboard layout (app/dashboard/layout.tsx):
import { Sidebar } from '@/components/layout/Sidebar'
import { TopBar } from '@/components/layout/TopBar'
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="flex h-screen bg-gray-100">
<Sidebar className="w-64 bg-white shadow-lg" />
<div className="flex-1 flex flex-col">
<TopBar className="bg-white shadow-sm" />
<main className="flex-1 overflow-y-auto p-6">
{children}
</main>
</div>
</div>
)
}
Use in page (app/dashboard/page.tsx):
export default function DashboardPage() {
return (
<div>
{/* Dashboard content */}
</div>
)
}
Design System
Colors
- Primary:
blue-600, Secondary:gray-600 - Success:
green-600, Warning:yellow-600, Error:red-600 - Neutral:
gray-100togray-900
Spacing
Use consistent scale: p-1 (4px), p-2 (8px), p-4 (16px), p-6 (24px), p-8 (32px)
Typography
- Headings:
text-4xl,text-3xl,text-2xl,text-xl - Body:
text-base(16px) - Weights:
font-normal,font-medium,font-semibold,font-bold
Advanced Guides
For detailed implementations:
- Component Library - Complete reusable Vue components with TypeScript
- TailwindCSS v4 Patterns - Advanced styling (works with both frameworks)
- NuxtJS Composables - State management and auto-imports (Vue-specific)
- React Hooks - Custom hooks and state management (React-specific)
- Animations - Vue transitions and TailwindCSS animations
- Examples - Complete Vue/NuxtJS mockup examples
- Deployment - Build and hosting guides for both frameworks
Scripts
Helper scripts available in scripts/ (Bash and PowerShell versions):
create-component.sh / .ps1 - Generate components with TypeScript boilerplate
# Linux/macOS - Vue component
./scripts/create-component.sh ComponentName ui vue
# Linux/macOS - React component
./scripts/create-component.sh ComponentName ui react
# Windows - Vue component
.\scripts\create-component.ps1 -ComponentName ComponentName -Type ui -Framework vue
# Windows - React component
.\scripts\create-component.ps1 -ComponentName ComponentName -Type ui -Framework react
build-deploy.sh / .ps1 - Build and prepare for deployment
# Linux/macOS
./scripts/build-deploy.sh
# Windows
.\scripts\build-deploy.ps1
NuxtJS CLI commands:
npx nuxi add component ComponentName # Add new component
npx nuxi add page pageName # Add new page
npx nuxi add layout layoutName # Add new layout
Next.js CLI commands:
# No built-in CLI for components, use scripts above
# Or manually create files in app/ or components/
Troubleshooting
NuxtJS (Vue)
TailwindCSS v4 not working:
- Restart dev server after nuxt.config.ts changes
- Verify
@import "tailwindcss";in your CSS file - Ensure
@tailwindcss/viteplugin is in vite.plugins array - Check CSS file is imported in nuxt.config.ts or app.vue
- Run
npx nuxi prepareto regenerate types
TypeScript errors:
- Install Volar extension (not Vetur)
- Run
npx nuxi prepareto generate types - Restart TypeScript server in VS Code
Auto-imports not working:
rm -rf .nuxt
npx nuxi prepare
npm run dev
HMR issues:
rm -rf .nuxt node_modules/.cache
npm run dev
Large bundle size:
- Use lazy loading:
defineAsyncComponent(() => import('./Component.vue')) - Analyze with:
npx nuxi analyze
Next.js (React)
TailwindCSS not working:
- Check
tailwind.config.tshas correct content paths - Verify
@import "tailwindcss";in app/globals.css - Restart dev server after config changes
- Clear
.nextfolder:rm -rf .next && npm run dev
TypeScript errors:
- Ensure tsconfig.json is properly configured
- Run
npm run buildto see full type checking - Restart TypeScript server in VS Code
Server vs Client Components:
- Use
'use client'directive at top of file for interactive components - Server Components (default) cannot use hooks or event handlers
- Client Components can use useState, useEffect, onClick, etc.
Build errors:
rm -rf .next node_modules/.cache
npm install
npm run build
Large bundle size:
- Use dynamic imports:
const Component = dynamic(() => import('./Component')) - Analyze with:
npm run build(shows bundle sizes)
Best Practices
Common (Both Frameworks)
- Component Design: Small, single-purpose, reusable
- TypeScript: Clear interfaces for props and component APIs
- TailwindCSS: Prefer utilities over custom CSS
- Responsive: Mobile-first approach
- Performance: Use SSR/SSG when appropriate, lazy load large components
- Accessibility: ARIA labels and keyboard navigation
- Code Organization: Group related components, consistent naming
NuxtJS (Vue) Specific
- Composables: Extract shared logic (auto-imported)
- Auto-imports: Leverage Nuxt's auto-import system for components and composables
- File-based Routing: Use pages/ directory for automatic routing
- Layouts: Create reusable layouts for consistent UI structure
- SEO: Use
useHead()anduseSeoMeta()for meta tags
Next.js (React) Specific
- Server Components: Default to Server Components, use Client Components only when needed
- Data Fetching: Use async Server Components for data fetching
- Metadata API: Use
generateMetadata()for dynamic SEO tags - Image Optimization: Use Next.js
<Image>component for automatic optimization - Route Handlers: Use route.ts for API endpoints in app/api/
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.