Skip to main content

Project Architecture

This tutorial walks you through building a complete e-commerce web store inspired by Mercado Libre, using HTML, CSS, and TypeScript. You’ll learn professional development practices including BEM methodology, responsive design, and modern JavaScript patterns.

What You’ll Build

A fully functional product catalog with:
  • Responsive header with search and navigation
  • Hero banner with call-to-action
  • Dynamic product grid loaded from an API
  • Shopping cart with real-time updates
  • Professional footer with multiple sections

Project Structure

ml-store/
├── index.html          # Main HTML structure
├── src/
│   ├── style.css       # All component styles
│   └── main.ts         # Application logic
└── public/
    └── favicon.svg     # Site icon

Technology Stack

HTML5

Semantic markup with modern elements like <header>, <nav>, <main>, <article>, and <footer>

CSS3

Custom properties (variables), Flexbox, Grid, animations, and BEM methodology

TypeScript

Type-safe JavaScript with interfaces, enums, generics, and async/await

Key Concepts Covered

BEM Methodology

The entire project uses BEM (Block Element Modifier) naming convention:
/* Block: Independent component */
.header { }

/* Element: Part of the block */
.header__logo { }
.header__search { }
.header__nav { }

/* Modifier: Variation of element */
.header__nav-link--cart { }
BEM makes your CSS predictable and maintainable. You’ll never have naming conflicts or specificity wars.

Component-Based Structure

Each major section is a self-contained component:
  1. Header (.header) - Navigation and branding
  2. Hero (.hero) - Marketing banner
  3. Benefits (.benefits) - Feature highlights
  4. Products (.products) - Product catalog
  5. Product Card (.product-card) - Reusable product display
  6. Footer (.footer) - Site information

State Management

The application uses a centralized state object:
interface AppState {
  status: LoadingState;     // Current loading state
  products: Product[];      // Array of products
  error: string | null;     // Error message if any
}
This single source of truth makes the app predictable and easy to debug.

Design System

The project implements a complete design system with CSS variables:
:root {
  /* Colors */
  --color-primary: #FFE600;        /* Mercado Libre yellow */
  --color-secondary: #3483FA;      /* ML blue */
  
  /* Typography */
  --font-size-base: 1rem;
  --font-size-xl: 1.25rem;
  
  /* Spacing (4px scale) */
  --spacing-sm: 0.5rem;            /* 8px */
  --spacing-md: 1rem;              /* 16px */
  --spacing-lg: 1.5rem;            /* 24px */
  
  /* Shadows */
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
}
Using CSS variables makes your design system flexible. Change one value and it updates everywhere.

API Integration

The project fetches real product data from the Platzi Fake Store API:
const API_URL = "https://api.escuelajs.co/api/v1/products";

async function fetchProducts(limit: number = 20): Promise<Product[]> {
  const response = await fetch(`${API_URL}?limit=${limit}`);
  if (!response.ok) {
    throw new Error(`Error HTTP: ${response.status}`);
  }
  return await response.json();
}

Responsive Design Strategy

Mobile-First Approach: The base styles work on mobile, then we enhance for larger screens. CSS Grid Auto-Responsive:
.products__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--spacing-lg);
}
This creates a responsive grid without media queries - it automatically adjusts columns based on available space.

Data Flow

Understand how data flows through the application:
1

User Action

User clicks “Cargar Productos” button
2

State Update

appState.status changes to LoadingState.Loading
3

UI Update

updateUI() function shows loading spinner
4

API Call

fetchProducts() requests data from server
5

Success

Products saved to appState.products, status becomes Success
6

Render

renderProducts() generates HTML for each product

File Organization

index.html

  • Semantic HTML structure
  • Accessibility attributes (ARIA labels)
  • SEO meta tags
  • Organized into logical sections

style.css

  • CSS reset for consistency
  • CSS variables for design tokens
  • Components organized by BEM blocks
  • Comprehensive comments explaining every concept

main.ts

  • TypeScript interfaces for type safety
  • Enums for state management
  • Helper functions for common tasks
  • Event delegation for performance
  • Async/await for API calls

Learning Path

Follow these pages in order to build the complete project:
  1. Header Component - Navigation, search, and sticky positioning
  2. Hero Section - Gradients, centering, and call-to-action buttons
  3. Product Catalog - Grid layouts and responsive design
  4. Shopping Cart - Map data structure and state management
  5. Footer Component - Multi-column layouts
  6. API Integration - Fetch, async/await, error handling
  7. State Management - Centralized state and UI updates

Best Practices Demonstrated

Semantic HTML - Using the right elements for better SEO and accessibility
BEM Naming - Consistent, collision-free CSS class names
CSS Variables - Maintainable design system
TypeScript - Type safety prevents runtime errors
Event Delegation - Efficient event handling for dynamic content
Error Handling - Try/catch blocks for robust applications
Loading States - Better UX with loading and error feedback

Next Steps

Ready to start building? Head to the Header Component page to create your first component!

Header Component

Build the navigation bar with logo, search, and cart

Product Catalog

Create a responsive product grid with CSS Grid

Build docs developers (and LLMs) love