Skip to main content

Installation Guide

This guide covers everything you need to set up Pokémon Explorer on your local machine for development, customization, or contribution.
Pokémon Explorer has zero dependencies—no npm packages, no build tools, no configuration files. It’s pure HTML, CSS, and JavaScript.

Prerequisites

Before you begin, ensure you have:

Web Browser

Modern browser (Chrome, Firefox, Safari, Edge)

Text Editor

VS Code, Sublime, Atom, or any code editor

Git (Optional)

For cloning the repository

Local Server (Optional)

Python, Node.js, or any HTTP server
No Node.js, npm, or build tools are required. This is intentionally a vanilla JavaScript project.

Installation Steps

1. Clone the Repository

1

Clone via HTTPS

git clone https://github.com/mueses1/PokeApi.git
cd PokeApi
2

Alternative: Clone via SSH

git clone [email protected]:mueses1/PokeApi.git
cd PokeApi
3

Alternative: Download ZIP

  1. Visit https://github.com/mueses1/PokeApi
  2. Click the green “Code” button
  3. Select “Download ZIP”
  4. Extract the ZIP file to your desired location

2. Project Structure

After cloning, you’ll see this structure:
PokeApi/
├── index.html          # Main HTML file - entry point
├── styles.css          # Complete styling (1498 lines)
├── logica.js           # All JavaScript logic (1067+ lines)
├── Assets/
│   └── PokeBola.png    # Pokéball favicon
└── README.md           # Project documentation
All application code is in just three files: index.html, styles.css, and logica.js. This makes it incredibly easy to understand and modify.

3. Choose Your Development Method

Simplest Method (with limitations)
# Just open the file
open index.html          # macOS
start index.html         # Windows
xdg-open index.html      # Linux
Using file:// protocol may cause issues with:
  • External resources (fonts, CDN libraries)
  • CORS policies
  • Some browser APIs

File Breakdown

index.html (75 lines)

The main HTML structure with semantic markup:
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pokédex</title>
    <link rel="stylesheet" href="styles.css">
    <link rel="icon" href="Assets/PokeBola.png" type="image/x-icon">
    
    <!-- Driver.js CDN for interactive tour -->
    <link rel="stylesheet" href="https://unpkg.com/driver.js/dist/driver.min.css">
    <script src="https://unpkg.com/driver.js/dist/driver.min.js"></script>
</head>
<body>
    <div class="container">
        <header>
            <h1>Pokémon Explorer</h1>
            <p class="subtitle">Descubre y explora el mundo Pokémon</p>
            <button id="startTour" class="tour-button">Guía Interactiva</button>
        </header>
        
        <!-- Controls Section -->
        <div class="controls">
            <div class="control-row">
                <!-- Search Input -->
                <div class="control-group" id="search-section">
                    <label for="searchInput">Buscar</label>
                    <div class="search-input">
                        <input type="text" id="searchInput" 
                               placeholder="Ej: pikachu, fuego, rojo...">
                        <div class="search-suggestions" id="searchSuggestions"></div>
                    </div>
                    <div class="error-message" id="searchError"></div>
                </div>
                
                <!-- Type Filter -->
                <div class="control-group" id="type-filter-section">
                    <label for="typeFilter">Filtrar por Tipo</label>
                    <select id="typeFilter">
                        <option value="">Elige el tipo</option>
                    </select>
                </div>
                
                <!-- Generation Filter -->
                <div class="control-group" id="generation-filter-section">
                    <label for="generationFilter">Generación</label>
                    <select id="generationFilter">
                        <option value="">Todas las generaciones</option>
                        <option value="1">Gen I - Kanto (1-151)</option>
                        <!-- ... More generations ... -->
                    </select>
                </div>
            </div>
        </div>
    </div>
    
    <!-- Loading Spinner -->
    <div class="loading" id="loading">
        <div class="spinner"></div>
        <p>Cargando Pokémon...</p>
    </div>
    
    <!-- Pokémon Grid -->
    <div class="pokemon-grid" id="pokemonGrid"></div>
    
    <!-- No Results Message -->
    <div class="no-results" id="noResults" style="display: none;">
        <div class="no-results-icon">😕</div>
        <p>No se encontraron Pokémon con los criterios seleccionados</p>
    </div>
    
    <!-- Pagination -->
    <div class="pagination" id="pagination"></div>
    
    <!-- Arcade Pixel Effects -->
    <div class="arcade-pixels"></div>
    
    <script src="logica.js"></script>
</body>
</html>
The HTML uses semantic elements and ARIA-friendly structure for accessibility.

logica.js (1067+ lines)

The complete application logic in a single class:
// Class-based architecture from logica.js:2
class PokemonExplorer {
    constructor() {
        // API Configuration
        this.API_BASE_URL = 'https://pokeapi.co/api/v2';
        
        // Constants for translations and mappings
        this.constants = {
            typeTranslations: { /* 18 types */ },
            abilityTranslations: { /* 70+ abilities */ },
            colorTranslations: { /* 10 colors */ },
            habitatTranslations: { /* 9 habitats */ },
            searchKeywords: { /* Spanish to English mappings */ },
            typeColors: { /* Gradient backgrounds for each type */ },
            genRanges: { /* ID ranges for each generation */ }
        };
        
        // Application State
        Object.assign(this, {
            currentPage: 1,
            pokemonPerPage: 12,
            allPokemon: [],
            filteredPokemon: [],
            pokemonTypes: [],
            pokemonNames: [],
            searchTimeout: null,
            pokemonById: new Map(),
            pokemonByName: new Map(),
            audioActivated: false
        });
        
        // DOM Element References
        this.elements = {
            searchInput: document.getElementById('searchInput'),
            typeFilter: document.getElementById('typeFilter'),
            generationFilter: document.getElementById('generationFilter'),
            loading: document.getElementById('loading'),
            pokemonGrid: document.getElementById('pokemonGrid'),
            pagination: document.getElementById('pagination')
        };
        
        // Initialize
        this.setupEventListeners();
        this.loadInitialData();
    }
    
    // ... 60+ methods for all functionality
}
Key Methods:
// Load initial types, colors, and habitats
async loadInitialData() { ... }

// Load Pokémon in batches
async loadMissingPokemon(list, key) { ... }

// Fetch detailed data for a single Pokémon
async fetchPokemonDetails(idOrName) { ... }

// Load all Pokémon of a specific type
async loadPokemonByType(type) { ... }
// Handle search input with debouncing
handleSearch(query) { ... }

// Parse smart search queries
parseSmartSearch(query) { ... }

// Apply all active filters
async applyFilters() { ... }

// Internal filter logic
_applyPokemonFilters(pokemonList, criteria) { ... }
// Display Pokémon cards on current page
displayPokemon() { ... }

// Create individual Pokémon card
createPokemonCard(pokemon) { ... }

// Update pagination controls
updatePagination() { ... }
// Translate keys to Spanish
translate(key, translationMap) { ... }

// Play Pokémon cry audio
playPokemonCry(cryUrl, button) { ... }

// Show/hide loading spinner
showLoading(show, message) { ... }

// Show/hide error messages
showError(message) { ... }

styles.css (1498 lines)

Complete styling with modern CSS features:
/* Arcade theme with neon effects - from styles.css:1 */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Arial', sans-serif;
    background: #18182a;
    min-height: 100vh;
    overflow-x: hidden;
}

/* Animated neon borders - styles.css:21 */
body::before {
    content: "";
    position: fixed;
    height: 6px;
    background: linear-gradient(90deg, #ff0055 0%, #fff900 50%, #00eaff 100%);
    filter: blur(1.5px) brightness(1.2);
    animation: neon-move 3s linear infinite alternate;
}

/* Glassmorphic Pokémon cards - styles.css:632 */
.pokemon-card {
    background: linear-gradient(145deg, rgba(255,255,255,0.1), rgba(255,255,255,0.05));
    backdrop-filter: blur(20px);
    border: 2px solid rgba(255,255,255,0.2);
    border-radius: 20px;
    box-shadow: 0 8px 32px rgba(0,0,0,0.3);
    transition: all 0.3s ease;
}

.pokemon-card:hover {
    transform: translateY(-8px) scale(1.02);
    box-shadow: 0 20px 40px rgba(0,0,0,0.4);
}
Styling Features:
  • Responsive Grid: 4 columns on desktop, 2-3 on tablet, 1 on mobile
  • Type Colors: Each Pokémon type has unique gradient backgrounds
  • Glassmorphism: Frosted glass effect with blur and transparency
  • Arcade Aesthetics: Neon borders, pixel effects, retro fonts
  • Animations: Smooth transitions, hover effects, loading spinners

Development Workflow

Making Changes

1

Edit Files

Open files in your editor and make changes:
  • HTML: Modify structure in index.html
  • CSS: Update styles in styles.css
  • JavaScript: Change logic in logica.js
2

Save & Reload

  • Manual: Save files and refresh browser (F5)
  • Live Server: Changes auto-reload
3

Test Changes

  • Check in browser DevTools (F12)
  • Test on different screen sizes
  • Verify console for errors

Browser DevTools

F12 or Cmd+Option+I (Mac) / Ctrl+Shift+I (Windows)
Use the Network tab to monitor PokeAPI requests and the Console tab to debug JavaScript errors.

Customization Examples

Change Pokémon Per Page

// In logica.js:116, change from 12 to your preferred number
this.pokemonPerPage = 20;  // Show 20 Pokémon per page

Modify Color Scheme

/* In styles.css:9, change the background color */
body {
    background: #1a1a2e;  /* Change to your preferred dark color */
}

/* Change neon border colors in styles.css:30 */
background: linear-gradient(90deg, #your-color-1, #your-color-2, #your-color-3);

Add Custom Filters

To add a new filter dropdown:
  1. Add HTML (in index.html):
<div class="control-group">
    <label for="customFilter">Your Filter</label>
    <select id="customFilter">
        <option value="">All</option>
    </select>
</div>
  1. Add to DOM references (in logica.js:130):
this.elements = {
    // ... existing elements
    customFilter: document.getElementById('customFilter')
};
  1. Add event listener (in logica.js:159):
this.elements.customFilter.addEventListener('change', () => this.applyFilters());
  1. Implement filter logic (in logica.js:531):
_applyPokemonFilters(pokemonList, criteria) {
    return pokemonList.filter(p => {
        // Add your custom filter condition
        if (criteria.customFilter && p.yourProperty !== criteria.customFilter) {
            return false;
        }
        // ... existing filters
        return true;
    });
}

Environment Setup

{
  "recommendations": [
    "ritwickdey.liveserver",        // Live Server for auto-reload
    "esbenp.prettier-vscode",       // Code formatting
    "dbaeumer.vscode-eslint",       // JavaScript linting
    "bradlc.vscode-tailwindcss",    // CSS IntelliSense
    "formulahendry.auto-rename-tag" // Auto rename HTML tags
  ]
}

Git Configuration

Set up Git for contributions:
# Configure your identity
git config user.name "Your Name"
git config user.email "[email protected]"

# Create a new branch for your changes
git checkout -b feature/your-feature-name

# Make changes, then stage and commit
git add .
git commit -m "Add: your feature description"

# Push to your fork
git push origin feature/your-feature-name

Troubleshooting

Cause: Slow network or PokeAPI rate limitingSolution:
  • Check browser console for 429 errors
  • Wait a moment and refresh
  • Images use lazy loading, so they load as you scroll
Cause: JavaScript error or DOM not readySolution:
  • Check browser console for errors
  • Ensure logica.js is loading after DOM elements
  • Verify the searchSuggestions element exists
Cause: Browser autoplay policiesSolution:
  • Click the 🔊 button once to activate audio
  • Check browser console for audio errors
  • Ensure PokeAPI cry URLs are accessible
Cause: CSS file path or cache issuesSolution:
  • Verify styles.css is in the same directory as index.html
  • Hard refresh: Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac)
  • Check Network tab in DevTools to confirm CSS loaded
Cause: Port already in use or command not foundSolution:
# Try a different port
python3 -m http.server 3000

# Or find what's using port 8000
# macOS/Linux:
lsof -i :8000

# Windows:
netstat -ano | findstr :8000

Performance Optimization

Image Optimization

Images use loading="lazy" attribute for better performance

Debounced Search

300ms delay prevents excessive API calls while typing

Map Data Structures

Uses Map() for O(1) Pokémon lookups by ID and name

Batch API Calls

Loads Pokémon in batches of 50 using Promise.all()
// Debounced search from logica.js:367
this.searchTimeout = setTimeout(() => this.performSearch(query), 300);

// Batch loading from logica.js:281
const batchSize = 50;
for (let i = 0; i < needed.length; i += batchSize) {
    const batch = needed.slice(i, i + batchSize);
    const newPokemon = await Promise.all(
        batch.map(p => this.fetchPokemonDetails(p))
    );
}

Next Steps

Explore Features

Learn how to use all the interactive features

Contribute

Fork the repo and submit pull requests on GitHub
Ready to contribute? Check the GitHub repository for open issues and contribution guidelines.

Build docs developers (and LLMs) love