--- name: favicon description: "Generate favicons and app icons for Next.js projects. Creates all required sizes, formats, and configures metadata." allowed-tools: Read, Glob, Grep, Write, Edit, Bash, WebFetch --- # Favicon Generator Generate complete favicon sets for Next.js projects. ## Workflow ### Step 1: Auto-Detect App Information **IMPORTANT:** Before asking the user anything, scan the codebase to extract: ```bash # Check these files in order: ``` #### 1. Package.json ```typescript // Read package.json for name and description { "name": "my-app", // App name "description": "..." // App description } ``` #### 2. Next.js Metadata (app/layout.tsx) ```typescript // Look for metadata export export const metadata: Metadata = { title: "App Title", // App name description: "...", // App description }; // Or metadataBase, applicationName ``` #### 3. README.md ```markdown # App Name <- Extract from H1 Description paragraph <- Extract first paragraph ``` #### 4. Tailwind Config (tailwind.config.ts) ```typescript // Look for custom colors in theme.extend.colors theme: { extend: { colors: { primary: "#6366f1", // Brand color brand: { ... } } } } ``` #### 5. CSS Variables (app/globals.css) ```css :root { --primary: #6366f1; /* Brand color */ --brand-color: ...; } ``` #### 6. Existing Favicon/Icons ```bash # Check if icons already exist public/favicon.ico public/apple-touch-icon.png app/icon.tsx app/icon.png ``` ### Step 2: Present Findings & Confirm After scanning, present what was found: ``` I found the following from your codebase: App name: Striggo Description: A study platform for professional certification exams Brand color: #8b5cf6 (from Tailwind config) Existing icons: None found Should I generate a favicon based on this? Or would you like to customize? ``` Only ask questions if: - App name is missing or unclear - No brand colors found (suggest based on app type) - User wants to override detected values ### Step 3: Choose Generation Method Based on user input, choose one of these approaches: --- ## Option A: Generate from Description (No Source Image) ### A1: Text/Initial-Based Icon Best for: Professional SaaS apps, clean minimal branding. ```typescript // app/icon.tsx import { ImageResponse } from "next/og"; export const runtime = "edge"; export const contentType = "image/png"; export const size = { width: 32, height: 32 }; export default function Icon() { return new ImageResponse( (
{/* First letter or initials of app name */} S
), { ...size } ); } ``` Create matching `apple-icon.tsx`: ```typescript // app/apple-icon.tsx import { ImageResponse } from "next/og"; export const runtime = "edge"; export const contentType = "image/png"; export const size = { width: 180, height: 180 }; export default function AppleIcon() { return new ImageResponse( (
S
), { ...size } ); } ``` ### A2: Emoji-Based Icon Best for: Fun apps, MVPs, quick prototypes. ```typescript // app/icon.tsx import { ImageResponse } from "next/og"; export const runtime = "edge"; export const contentType = "image/png"; export const size = { width: 32, height: 32 }; export default function Icon() { return new ImageResponse( (
{/* Choose emoji that represents the app */} 🚀
), { ...size } ); } ``` ### A3: SVG Icon (Scalable, Dark Mode Support) Best for: Technical apps, developer tools. ```typescript // app/icon.tsx import { ImageResponse } from "next/og"; export const runtime = "edge"; export const contentType = "image/png"; export const size = { width: 32, height: 32 }; export default function Icon() { return new ImageResponse( (
{/* Simple geometric shape or symbol */}
), { ...size } ); } ``` ### Design Guidelines by App Type | App Type | Style | Colors | Icon Ideas | |----------|-------|--------|------------| | Finance/Banking | Minimal, professional | Blue, green, dark | Letter, shield, chart | | Productivity | Clean, modern | Purple, blue | Checkmark, layers, grid | | Social/Community | Friendly, warm | Orange, pink | Heart, people, chat | | Developer Tools | Technical, dark | Dark gray, cyan | Terminal, brackets, code | | E-commerce | Bold, trustworthy | Orange, blue | Cart, bag, tag | | Health/Fitness | Energetic, fresh | Green, teal | Heart, leaf, pulse | | Education | Approachable | Blue, yellow | Book, cap, lightbulb | ### Color Suggestions Based on app purpose, suggest colors: ```typescript const colorSchemes = { professional: "linear-gradient(135deg, #1e3a8a 0%, #3b82f6 100%)", creative: "linear-gradient(135deg, #ec4899 0%, #8b5cf6 100%)", growth: "linear-gradient(135deg, #059669 0%, #10b981 100%)", energy: "linear-gradient(135deg, #ea580c 0%, #f59e0b 100%)", trust: "linear-gradient(135deg, #0284c7 0%, #06b6d4 100%)", minimal: "#0f172a", // Solid dark light: "#f8fafc", // Solid light with colored icon }; ``` --- ## Option B: Generate from Existing Source Image ### B1: Using Sharp (Recommended) ```bash bun add sharp ``` ```typescript // scripts/generate-favicons.ts import sharp from "sharp"; import { join } from "path"; const SOURCE = "source-icon.png"; const OUTPUT_DIR = "public"; const sizes = [ { name: "favicon-16x16.png", size: 16 }, { name: "favicon-32x32.png", size: 32 }, { name: "apple-touch-icon.png", size: 180 }, { name: "android-chrome-192x192.png", size: 192 }, { name: "android-chrome-512x512.png", size: 512 }, ]; async function generateFavicons() { for (const { name, size } of sizes) { await sharp(SOURCE) .resize(size, size) .png() .toFile(join(OUTPUT_DIR, name)); console.log(`Generated: ${name}`); } // Create ICO await sharp(SOURCE) .resize(32, 32) .toFile(join(OUTPUT_DIR, "favicon.ico")); } generateFavicons(); ``` ### B2: Using ImageMagick ```bash brew install imagemagick # Generate all sizes convert source.png -resize 16x16 public/favicon-16x16.png convert source.png -resize 32x32 public/favicon-32x32.png convert source.png -resize 180x180 public/apple-touch-icon.png convert source.png -resize 192x192 public/android-chrome-192x192.png convert source.png -resize 512x512 public/android-chrome-512x512.png convert source.png -resize 32x32 -define icon:auto-resize=32,16 public/favicon.ico ``` --- ## Step 3: Create Web Manifest ```json // public/site.webmanifest { "name": "APP_NAME", "short_name": "APP_SHORT", "description": "APP_DESCRIPTION", "icons": [ { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } ], "theme_color": "#PRIMARY_COLOR", "background_color": "#ffffff", "display": "standalone", "start_url": "/" } ``` Or use dynamic manifest: ```typescript // app/manifest.ts import type { MetadataRoute } from "next"; export default function manifest(): MetadataRoute.Manifest { return { name: "App Name", short_name: "App", description: "App description", start_url: "/", display: "standalone", background_color: "#ffffff", theme_color: "#6366f1", icons: [ { src: "/android-chrome-192x192.png", sizes: "192x192", type: "image/png", }, { src: "/android-chrome-512x512.png", sizes: "512x512", type: "image/png", }, ], }; } ``` ## Step 4: Configure Metadata (if using static files) ```typescript // app/layout.tsx import type { Metadata } from "next"; export const metadata: Metadata = { title: "App Name", description: "App description", icons: { icon: [ { url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" }, { url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" }, ], apple: [ { url: "/apple-touch-icon.png", sizes: "180x180", type: "image/png" }, ], }, manifest: "/site.webmanifest", }; ``` ## Interactive Flow When running `/favicon`: ### 1. First, scan the codebase (silently): ```bash # Read these files cat package.json cat app/layout.tsx cat README.md cat tailwind.config.ts cat app/globals.css ls public/favicon* app/icon* 2>/dev/null ``` ### 2. Present findings: ``` I scanned your codebase and found: App name: Striggo Description: A study platform for professional certification exams Brand color: #8b5cf6 (from tailwind.config.ts) Existing icons: None I'll generate a favicon with: - Letter "S" on purple gradient background - Professional style (matching education/learning apps) Proceed with this? Or customize (name/color/style)? ``` ### 3. If info is missing, ask only what's needed: ``` I couldn't detect a brand color. What color should I use? 1. Purple (education/learning) 2. Blue (trust/professional) 3. Green (growth/success) 4. Custom hex code > 1 ``` ### 4. Generate: - `app/icon.tsx` - Dynamic 32x32 favicon - `app/apple-icon.tsx` - Dynamic 180x180 Apple icon - `app/manifest.ts` - PWA manifest - Update `app/layout.tsx` with theme colors ## Files Checklist ### For Dynamic Icons (Option A) ``` app/ ├── icon.tsx # 32x32 favicon (generated) ├── apple-icon.tsx # 180x180 Apple icon (generated) └── manifest.ts # PWA manifest ``` ### For Static Icons (Option B) ``` public/ ├── favicon.ico ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── android-chrome-192x192.png ├── android-chrome-512x512.png └── site.webmanifest ``` ## Troubleshooting | Issue | Solution | |-------|----------| | Icon not updating | Clear cache, restart dev server | | Apple icon not showing | Must be exactly 180x180 PNG | | Dynamic icon 500 error | Check ImageResponse syntax | | Emoji not rendering | Use system emoji font | | Gradient looks wrong | Use standard CSS gradient syntax |