A modern, interactive web application for creating and managing custom Pokémon for Egglocke challenges.
Features • Tech Stack • Getting Started • Usage • Screenshots
The Egglocke Generator is a full-stack web application designed for Pokémon players who want to create custom Pokémon for their Egglocke runs. Built with the latest Next.js 16 and a modern tech stack, it provides a seamless experience for generating, customizing, and managing Pokémon with French language support.
- 493 Gen 1-4 Pokémon available via PokéAPI integration
- Smart search with accent-insensitive filtering (type "etrein" to find "Étreinte")
- Custom nicknames (required field)
- Gender selection (Male ♂ / Female ♀ / Genderless ⚲)
- Shiny variant toggle with sprite preview
- Learned moves: Select from moves the Pokémon can naturally learn
- Random moves: Generate random moves with instant preview and reroll capability
- 1000+ moves available from PokéAPI
- Visual separation between learned and other moves in dropdown
- French translations for all moves with automatic fallback
- Searchable dropdowns (Combobox) for Pokémon and moves
- Real-time validation with React Hook Form + Zod
- Responsive design with Tailwind CSS v4
- Accessible components using Shadcn/UI
- Spoiler system for creator names (click to reveal)
- PostgreSQL database (Neon serverless)
- Drizzle ORM for type-safe queries
- Server Actions for form submission (no API routes needed)
- Aggressive caching (24h) for optimal performance
- Gallery view for all created Pokémon
- Next.js 16 - React framework with App Router and Turbopack
- TypeScript - Strict mode for type safety
- React Hook Form - Performant form management
- Tailwind CSS v4 - Modern utility-first CSS
- Shadcn/UI - Accessible component library
- Neon PostgreSQL - Serverless PostgreSQL
- Drizzle ORM - TypeScript ORM
- Zod v4 - Schema validation
- PokéAPI v2 - Pokémon data source
- Server Actions for data mutations
- Server Components for optimal performance
- Optimistic caching with
unstable_cache - Static generation for homepage and gallery
- Node.js 18+ and pnpm
- PostgreSQL database (Neon recommended)
-
Clone the repository
git clone <repository-url> cd poke-generator
-
Install dependencies
pnpm install
-
Set up environment variables
Create a
.env.localfile:DATABASE_URL="postgresql://user:password@host/database?sslmode=require"
-
Push database schema
pnpm db:push
-
Run the development server
pnpm dev
-
Open your browser
Navigate to http://localhost:3000
- Select a Pokémon - Use the searchable dropdown to find your Pokémon (supports French names)
- Add a nickname - Give your Pokémon a unique name (required)
- Choose gender - Select Male, Female, or Genderless
- Toggle Shiny - Enable shiny variant if desired
- Select 4 moves:
- Choose "Capacité" to pick from all available moves
- Choose "Aléatoire" to generate a random move (with reroll option 🎲)
- Enter creator name - Add your name
- Submit - Create your Pokémon!
Navigate to the "Pokémon Créés" page to view all created Pokémon in a grid layout. Creator names are hidden by default (spoiler system) - click to reveal.
poke-generator/
├── app/
│ ├── api/
│ │ ├── moves/ # All moves API endpoint
│ │ └── pokemon/[id]/ # Pokemon details API
│ ├── created/ # Gallery page
│ └── page.tsx # Homepage
├── components/
│ ├── ui/ # Shadcn/UI components
│ │ ├── button.tsx
│ │ ├── combobox.tsx # Custom searchable dropdown
│ │ ├── input.tsx
│ │ ├── label.tsx
│ │ └── select.tsx
│ ├── pokemon-card.tsx # Card display component
│ └── pokemon-form.tsx # Main form component
├── lib/
│ ├── actions/
│ │ └── pokemon.ts # Server Actions
│ ├── api/
│ │ └── pokeapi.ts # PokéAPI integration
│ ├── db/
│ │ ├── index.ts # Database connection
│ │ └── schema.ts # Drizzle schema
│ └── validations/
│ └── pokemon.ts # Zod schemas
└── drizzle.config.ts # Drizzle Kit config
const normalizeString = (str: string) => {
return str
.toLowerCase()
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "");
};The Combobox automatically separates learned moves from other moves with a visual divider, making it easy to distinguish what the Pokémon can naturally learn.
Random moves are instantly generated when selected, with a reroll button (🎲) to try different options until you find the perfect move.
All Pokémon and move names are fetched in French from PokéAPI with automatic fallback to English if translations are unavailable.
export const createdPokemons = pgTable("created_pokemons", {
id: serial("id").primaryKey(),
pokemonId: integer("pokemon_id").notNull(),
pokemonName: varchar("pokemon_name", { length: 100 }).notNull(),
pokemonNameFr: varchar("pokemon_name_fr", { length: 100 }),
nickname: varchar("nickname", { length: 100 }),
gender: varchar("gender", { length: 20 }).notNull(),
isShiny: boolean("is_shiny").notNull().default(false),
moves: jsonb("moves").notNull(),
creatorName: varchar("creator_name", { length: 100 }).notNull(),
spriteUrl: varchar("sprite_url", { length: 255 }),
createdAt: timestamp("created_at").defaultNow(),
});- User-first: Every interaction is designed to be intuitive and efficient
- Type-safe: Full TypeScript coverage with strict mode
- Performance: Aggressive caching and static generation where possible
- Accessibility: Using Shadcn/UI components built on Radix UI primitives
- Modern: Latest versions of all technologies (Next.js 16, Tailwind v4, Zod v4)
Contributions are welcome! Please feel free to submit a Pull Request.
This project is open source and available under the MIT License.
- PokéAPI - For providing comprehensive Pokémon data
- Neon - For serverless PostgreSQL hosting
- Vercel - For Next.js and deployment platform
- Shadcn - For beautiful, accessible components
Built with ❤️ for the Pokémon community