Skip to main content

web-public Application

Marketing, Discovery & Animal Purchasing
Application Type: Public-Facing Marketing Site
Port: 3000
Users: Anonymous visitors, buyers
Status: In Development
Technology: Next.js 15 + Material UI + @reptidex/ui + @reptidex/core

Purpose & Responsibilities

web-public serves as ReptiDex’s primary marketing and discovery platform, providing an SEO-optimized, fast-loading experience for users discovering the platform, browsing animals, and learning about reptile care and breeding.

Core Features

Marketing & Landing

  • Homepage with hero sections and testimonials
  • About pages with platform story and mission
  • Pricing tiers and feature comparisons
  • SEO-optimized breed and location pages
  • Contact forms and lead generation

Animal Discovery

  • Advanced search with species/genetics filtering
  • Browse categories by species and morphs
  • Public animal profiles with image galleries
  • Breeder directory and public profiles
  • Purchase inquiry and contact system

Educational Content

  • Species-specific care guides
  • Breeding and genetics education
  • Interactive taxonomy browser
  • Resource library with videos and documents
  • Community-contributed content

SEO & Performance

  • Static generation for marketing content
  • Server-side rendering for dynamic pages
  • Optimized Core Web Vitals
  • Structured data for rich snippets
  • Progressive Web App features

Application Architecture

Technology Stack

Framework & Runtime:
  • Next.js 15 with App Router and Server Components
  • React 18 with concurrent features
  • TypeScript for type safety
  • Material UI components via @reptidex/ui
Shared Dependencies:
  • @reptidex/ui: Material UI theme, components, design system
  • @reptidex/core: API clients, business logic, state management
Data & State:
  • React Query for server state management
  • Zustand for client state management
  • Static generation with ISR for dynamic content
  • Optimistic updates for search interactions

Page Structure

app/
├── (marketing)/              # Marketing pages layout group
│   ├── page.tsx             # Homepage - hero, features, testimonials
│   ├── about/               # About ReptiDex and team
│   ├── pricing/             # Subscription plans and features
│   ├── contact/             # Contact forms and support
│   └── features/            # Feature deep-dive pages
├── search/                  # Animal search and filtering
│   ├── page.tsx            # Main search interface
│   └── results/            # Search results display
├── animals/
│   └── [id]/
│       ├── page.tsx        # Animal detail pages
│       └── pedigree/       # Pedigree visualization
├── breeders/
│   └── [slug]/
│       ├── page.tsx        # Public breeder profiles
│       └── animals/        # Breeder's animals
├── learn/                   # Educational content
│   ├── care-guides/        # Species care information
│   ├── genetics/           # Breeding education
│   ├── taxonomy/           # Species explorer
│   └── articles/           # Blog-style content
├── embed/                   # Embeddable widget previews
└── sitemap.xml             # Dynamic sitemap generation

Data Architecture

API Integration

Backend Service Integration:
  • repti-animal: Animal data, lineage, species information
  • repti-commerce: Public marketplace listings
  • repti-community: Search functionality and content
  • repti-media: Image galleries and file delivery
  • repti-core: Authentication for contact forms
Data Fetching Patterns:
// Static generation for SEO pages
export const generateStaticParams = async () => {
  const popularSpecies = await animalAPI.getPopularSpecies();
  return popularSpecies.map(species => ({ 
    slug: species.slug 
  }));
};

// ISR for frequently updated content
export const revalidate = 300; // 5 minutes

// Client-side for interactive search
const SearchResults = () => {
  const { data: results, isLoading } = useQuery({
    queryKey: ['search', filters],
    queryFn: () => searchAPI.animals(filters),
    staleTime: 30000, // 30 seconds
    gcTime: 300000,   // 5 minutes
  });

  return <ResultsGrid results={results} loading={isLoading} />;
};

Caching Strategy

Next.js Caching:
  • Static generation for marketing pages
  • ISR for animal and breeder profiles
  • Route handlers with cache headers
  • Image optimization with automatic WebP/AVIF
React Query Caching:
  • Search results: 30 second stale time
  • Animal profiles: 5 minute stale time
  • Species data: 1 hour stale time
  • Educational content: 24 hour stale time
CDN Caching:
  • Static assets: 1 year cache
  • API responses: 5 minute cache with SWR
  • Images: Automatic optimization and caching
  • Service worker for offline browsing

User Experience Features

Search & Discovery

Search Functionality:
const SearchInterface = () => {
  const [filters, setFilters] = useState({
    species: '',
    morphs: [],
    priceRange: [0, 10000],
    location: { radius: 50, center: null },
    availability: 'available',
    breederVerified: false
  });

  const { data: results, isLoading } = useAnimalSearch(filters);
  const { data: facets } = useSearchFacets(filters);

  return (
    <div className="search-layout">
      <SearchFilters 
        filters={filters} 
        facets={facets}
        onChange={setFilters} 
      />
      <SearchResults results={results} loading={isLoading} />
      <SearchPagination />
    </div>
  );
};
Filter Components:
  • Species dropdown with autocomplete
  • Multi-select morph combinations
  • Price range slider with currency formatting
  • Geographic radius search with map
  • Breeder verification and ratings
  • Advanced availability status

Animal Profiles

Animal Detail Features:
  • High-resolution image galleries with zoom
  • Comprehensive lineage and pedigree trees
  • Genetic trait breakdown and predictions
  • Breeder information and contact options
  • Similar animals and recommendations
  • Social sharing and bookmarking
SEO Optimization:
export const generateMetadata = async ({ params }) => {
  const animal = await animalAPI.getPublicAnimal(params.id);
  
  return {
    title: `${animal.name} - ${animal.species.commonName} | reptidex`,
    description: animal.description.slice(0, 160),
    openGraph: {
      title: `${animal.name} - Available at reptidex`,
      description: animal.description,
      images: [{ url: animal.primaryImage.url }],
      type: 'article',
    },
    twitter: {
      card: 'summary_large_image',
      title: animal.name,
      description: animal.description,
      images: [animal.primaryImage.url],
    },
    alternates: {
      canonical: `https://reptidex.com/animals/${animal.id}`,
    },
  };
};

Performance Optimization

Core Web Vitals

Target Metrics:
  • LCP (Largest Contentful Paint): < 1.8s
  • FID (First Input Delay): < 50ms
  • CLS (Cumulative Layout Shift): < 0.05
  • TTFB (Time to First Byte): < 200ms
Optimization Strategies:
  • Static generation for above-the-fold content
  • Image optimization with priority loading
  • Font preloading and optimization
  • Critical CSS inlining
  • Service worker for repeat visits

Image Optimization

Image Pipeline:
// Optimized image component
const OptimizedImage = ({ src, alt, priority = false }) => {
  return (
    <Image
      src={src}
      alt={alt}
      priority={priority}
      sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
      className="object-cover transition-opacity duration-300"
      placeholder="blur"
      blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..."
    />
  );
};
Features:
  • Automatic WebP/AVIF conversion
  • Responsive image sizing
  • Lazy loading with intersection observer
  • Blur placeholder while loading
  • CDN delivery with global edge caching

SEO & Marketing

Search Engine Optimization

Technical SEO:
  • Dynamic sitemap generation for all public content
  • Structured data for animals, breeders, and articles
  • Canonical URLs and proper redirects
  • Mobile-first responsive design
  • Fast loading speeds and Core Web Vitals
Content SEO:
// Structured data for animal listings
const generateAnimalStructuredData = (animal) => ({
  "@context": "https://schema.org",
  "@type": "Product",
  "name": animal.name,
  "description": animal.description,
  "image": animal.images.map(img => img.url),
  "brand": {
    "@type": "Brand",
    "name": animal.breeder.businessName
  },
  "offers": {
    "@type": "Offer",
    "price": animal.price,
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock",
    "seller": {
      "@type": "Organization",
      "name": animal.breeder.businessName
    }
  }
});

Lead Generation

Lead Capture:
  • Newsletter signup with genetic education content
  • Animal inquiry forms with breeder matching
  • Care guide downloads with email capture
  • Breeder profile creation CTAs
  • Pricing page with trial signup
Analytics & Tracking:
// Conversion tracking
const trackConversion = (event: string, data: any) => {
  // Google Analytics 4
  gtag('event', event, {
    event_category: 'conversion',
    event_label: data.source,
    value: data.value
  });

  // Custom analytics via @reptidex/core
  analytics.track(event, {
    ...data,
    timestamp: new Date(),
    sessionId: getSessionId(),
    page: window.location.pathname
  });
};

Educational Content

Content Management

Content Structure:
content/
├── care-guides/
│   ├── ball-python-care.mdx
│   ├── crested-gecko-setup.mdx
│   └── bearded-dragon-diet.mdx
├── genetics/
│   ├── understanding-inheritance.mdx
│   ├── morph-combinations.mdx
│   └── line-breeding-basics.mdx
├── species/
│   ├── python-regius.mdx
│   └── correlophus-ciliatus.mdx
└── articles/
    ├── breeding-season-prep.mdx
    └── humidity-control.mdx
Content Processing:
import { compileMDX } from 'next-mdx-remote/rsc';

export const getContentPage = async (slug: string) => {
  const source = await fs.readFile(`content/${slug}.mdx`, 'utf8');
  
  const { content, frontmatter } = await compileMDX({
    source,
    options: {
      parseFrontmatter: true,
      mdxOptions: {
        remarkPlugins: [remarkGfm, remarkToc],
        rehypePlugins: [rehypeHighlight, rehypeSlug],
      },
    },
    components: {
      Image: OptimizedImage,
      CareSheet: CareSheetComponent,
      GeneticsCalculator: GeneticsCalculatorComponent,
    },
  });

  return { content, frontmatter };
};

Integration & Embeds

Widget System

Available Widgets:
  • Animal profile cards for external sites
  • Breeder showcase displays
  • Care guide embeds
  • Species information widgets
  • Marketplace listing previews
Widget Implementation:
// Embeddable animal card
const EmbeddableAnimalCard = ({ animalId, theme = 'light' }) => {
  const { data: animal } = usePublicAnimal(animalId);
  
  if (!animal) return <CardSkeleton />;
  
  return (
    <Card className={`embed-card theme-${theme}`}>
      <CardMedia 
        component="img"
        image={animal.primaryImage.url}
        alt={animal.name}
      />
      <CardContent>
        <Typography variant="h6">{animal.name}</Typography>
        <Typography variant="body2" color="text.secondary">
          {animal.species.commonName}
        </Typography>
        <Typography variant="body2">
          {animal.price ? `$${animal.price}` : 'Contact for pricing'}
        </Typography>
      </CardContent>
      <CardActions>
        <Button 
          size="small" 
          href={`https://reptidex.com/animals/${animal.id}`}
          target="_blank"
        >
          View Details
        </Button>
      </CardActions>
    </Card>
  );
};

Security & Privacy

Security Implementation

Content Security Policy:
const cspHeader = `
  default-src 'self';
  script-src 'self' 'unsafe-eval' 'unsafe-inline' 
    vercel.live googletagmanager.com;
  style-src 'self' 'unsafe-inline' fonts.googleapis.com;
  img-src 'self' blob: data: *.reptidex.com;
  font-src 'self' fonts.gstatic.com;
  connect-src 'self' api.reptidex.com vitals.vercel-insights.com;
  media-src 'self' *.reptidex.com;
  frame-ancestors 'none';
`;
Input Sanitization:
import DOMPurify from 'isomorphic-dompurify';

const sanitizeUserInput = (input: string) => {
  return DOMPurify.sanitize(input, { 
    ALLOWED_TAGS: [],
    ALLOWED_ATTR: [],
    ALLOW_DATA_ATTR: false
  });
};

Testing & Quality

Testing Strategy

Unit Testing:
import { render, screen, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import SearchInterface from './SearchInterface';

const renderWithProviders = (ui: React.ReactElement) => {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false } }
  });
  
  return render(
    <QueryClientProvider client={queryClient}>
      {ui}
    </QueryClientProvider>
  );
};

describe('SearchInterface', () => {
  it('performs search when filters change', async () => {
    renderWithProviders(<SearchInterface />);
    
    const speciesSelect = screen.getByLabelText('Species');
    await userEvent.selectOptions(speciesSelect, 'ball-python');
    
    await waitFor(() => {
      expect(screen.getByText('Searching...')).toBeInTheDocument();
    });
  });
});
E2E Testing:
import { test, expect } from '@playwright/test';

test('user journey: search to animal detail', async ({ page }) => {
  await page.goto('/search');
  
  // Perform search
  await page.selectOption('[data-testid=species-filter]', 'ball-python');
  await page.click('[data-testid=search-button]');
  
  // Click first result
  await page.click('[data-testid=search-results] article:first-child');
  
  // Verify animal detail page
  await expect(page.locator('h1')).toBeVisible();
  await expect(page.locator('[data-testid=animal-gallery]')).toBeVisible();
  await expect(page.locator('[data-testid=contact-breeder]')).toBeVisible();
});

Monitoring & Analytics

Performance Monitoring

Core Metrics:
  • Web Vitals: Real User Monitoring via Vercel Analytics
  • Performance: Page load times and resource loading
  • Business: Conversion funnels and user behavior
  • Technical: API response times and error rates
Custom Analytics:
// Business event tracking
const trackBusinessEvent = (event: string, properties: any) => {
  // Vercel Analytics
  track(event, properties);
  
  // Custom telemetry via @reptidex/core
  analytics.track({
    event,
    properties: {
      ...properties,
      page: window.location.pathname,
      referrer: document.referrer,
      timestamp: new Date().toISOString()
    },
    context: {
      userAgent: navigator.userAgent,
      viewport: {
        width: window.innerWidth,
        height: window.innerHeight
      }
    }
  });
};

// Usage examples
trackBusinessEvent('animal_viewed', { animalId, species });
trackBusinessEvent('search_performed', { query, filters, resultCount });
trackBusinessEvent('breeder_contacted', { breederId, method });

Deployment & Infrastructure

Deployment Strategy

Docker Configuration:
FROM node:18-alpine AS base
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Dependencies
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile

# Build
COPY . .
RUN pnpm build

# Runtime
FROM node:18-alpine AS runner
WORKDIR /app
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=base /app/public ./public
COPY --from=base --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=base --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
Environment Configuration:
# API Configuration
NEXT_PUBLIC_API_URL=https://api.reptidex.com
NEXT_PUBLIC_CDN_URL=https://cdn.reptidex.com

# Analytics & Monitoring
NEXT_PUBLIC_VERCEL_ANALYTICS_ID=prj_xxx
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXX

# Feature Flags
NEXT_PUBLIC_POSTHOG_KEY=phc_xxx
NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com

# External Services
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_xxx
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=AIza_xxx

web-public serves as the primary entry point for ReptiDex, focusing on performance, SEO, and conversion optimization to drive user acquisition and engagement.