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
Clone via HTTPS
git clone https://github.com/mueses1/PokeApi.git
cd PokeApi
Alternative: Clone via SSH
Alternative: Download ZIP
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
File Protocol
Python Server
Node.js Server
VS Code
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
Recommended for Quick Setup # Python 3 (recommended)
python3 -m http.server 8000
# Python 2
python -m SimpleHTTPServer 8000
Then visit: http://localhost:8000 Python is pre-installed on macOS and most Linux distributions.
If You Have Node.js Installed # Using npx (no installation needed)
npx http-server -p 8000
# Or install globally
npm install -g http-server
http-server -p 8000
# Or use live-server for auto-reload
npx live-server --port=8000
Then visit: http://localhost:8000 Best for Active Development
Install Live Server extension
Open the project folder in VS Code
Right-click index.html
Select “Open with Live Server”
Live Server automatically reloads the page when you save changes—perfect for development!
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 : 100 vh ;
overflow-x : hidden ;
}
/* Animated neon borders - styles.css:21 */
body ::before {
content : "" ;
position : fixed ;
height : 6 px ;
background : linear-gradient ( 90 deg , #ff0055 0 % , #fff900 50 % , #00eaff 100 % );
filter : blur ( 1.5 px ) brightness ( 1.2 );
animation : neon-move 3 s linear infinite alternate ;
}
/* Glassmorphic Pokémon cards - styles.css:632 */
.pokemon-card {
background : linear-gradient ( 145 deg , rgba ( 255 , 255 , 255 , 0.1 ), rgba ( 255 , 255 , 255 , 0.05 ));
backdrop-filter : blur ( 20 px );
border : 2 px solid rgba ( 255 , 255 , 255 , 0.2 );
border-radius : 20 px ;
box-shadow : 0 8 px 32 px rgba ( 0 , 0 , 0 , 0.3 );
transition : all 0.3 s ease ;
}
.pokemon-card:hover {
transform : translateY ( -8 px ) scale ( 1.02 );
box-shadow : 0 20 px 40 px 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
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
Save & Reload
Manual : Save files and refresh browser (F5)
Live Server : Changes auto-reload
Test Changes
Check in browser DevTools (F12)
Test on different screen sizes
Verify console for errors
Chrome DevTools
Firefox Developer Tools
Safari Web Inspector
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:
Add HTML (in index.html):
< div class = "control-group" >
< label for = "customFilter" > Your Filter </ label >
< select id = "customFilter" >
< option value = "" > All </ option >
</ select >
</ div >
Add to DOM references (in logica.js:130):
this . elements = {
// ... existing elements
customFilter: document . getElementById ( 'customFilter' )
};
Add event listener (in logica.js:159):
this . elements . customFilter . addEventListener ( 'change' , () => this . applyFilters ());
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
Recommended VS Code Extensions
{
"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
Pokémon images not loading
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
Search suggestions not appearing
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
Cannot start local server
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
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.