← Back to Projects

Ixiptla - Archaeological Replicas Showcase

Ixiptla - Archaeological Replicas Showcase

Description

Ixiptla is a modern web application that presents a curated collection of meticulously crafted archaeological reproductions. Built with Astro.js and React, this platform combines performance with stunning visual presentation to bring ancient replicas to life in the digital realm. The project features interactive 3D models using Three.js, fully responsive design, and comprehensive internationalization support in English and Spanish.

Challenges

Solutions

3D Model Implementation

I leveraged React Three Fiber and Drei to create an abstracted 3D scene component that handles model loading, camera controls, and lighting. The implementation includes:

// Scene3D component handles all Three.js setup
export function Scene3D({
  modelPath = "/images/models/colibri.glb",
}: Scene3DProps) {
  const [autoRotate, setAutoRotate] = useState(false);
  const controlsRef = useRef<OrbitControlsImpl>(null);

  // Custom event system for external controls
  useEffect(() => {
    const handleResetCamera = () => {
      if (controlsRef.current) {
        controlsRef.current.reset();
      }
    };

    window.addEventListener("reset-camera", handleResetCamera);
    // Additional event handlers...

    return () => {
      window.removeEventListener("reset-camera", handleResetCamera);
      // Cleanup...
    };
  }, []);

  // Canvas, lighting, controls setup...
}

Internationalization Architecture

I designed a robust i18n system using:

  1. Language detection based on browser settings
  2. URL-based language routing (/en/, /es/)
  3. JSON-based translation files with nested keys
  4. Custom translation utility functions
// Translation utility function
export function useTranslations(lang: "en" | "es") {
  const translations = lang === "es" ? es : en;

  return function t(key: string) {
    const keys = key.split(".");
    let value: any = translations;
    for (const k of keys) {
      value = value[k];
      if (value === undefined) return key;
    }

    return value as string;
  };
}

Content Schema and Organization

I implemented a strongly typed content schema using Zod for validation, ensuring data integrity across all replicas:

const replicaSchema = z.object({
  id: z.string(),
  title: z.string(),
  culture: z.string(),
  period: z.string(),
  image: z.string(),
  description: z.string(),
  museum: z.string(),
  location: z.string(),
  dimensions: z.string().optional(),
  material: z.string().optional(),
  technique: z.string().optional(),
  has3DModel: z.boolean().optional(),
  slug: z.string(),
});

This approach enforces content consistency while providing flexibility for optional attributes.

Performance Optimizations

To ensure optimal performance while maintaining visual quality:

  1. Implemented responsive image loading with proper dimensions and WebP format
  2. Used lazy loading for off-screen content
  3. Optimized 3D model loading with suspense and fallbacks
  4. Leveraged Astro’s partial hydration for minimal JavaScript

Results

Visuals

Ixiptla - Archaeological Replicas Showcase - View 1
Ixiptla - Archaeological Replicas Showcase - View 2
Ixiptla - Archaeological Replicas Showcase - View 3
Ixiptla - Archaeological Replicas Showcase - View 4
Ixiptla - Archaeological Replicas Showcase - View 5
Ixiptla - Archaeological Replicas Showcase - View 6
Ixiptla - Archaeological Replicas Showcase - View 7
Ixiptla - Archaeological Replicas Showcase - View 8
Ixiptla - Archaeological Replicas Showcase - View 9
Ixiptla - Archaeological Replicas Showcase - View 10
Ixiptla - Archaeological Replicas Showcase - View 11